Introducción al desarrollo de intérpretes y lenguajes de programación

1

Aprende a desarrollar lenguajes de programación con intérpretes

2

Desarrolla LPP o Lenguaje de Programación Platzi

Construcción del lexer o tokenizador

3

¿Qué es análisis léxico? Funcionamiento del lexer y tokens

4

Estructura y definición de tokens en Python

5

Lectura de caracteres y tokens

6

Tokens ilegales, operadores de un solo carácter y delimitadores

7

Reconocimiento y diferenciación entre letras y números

8

Declaración y ejecución de funciones

9

Extensión del lexer: condicionales, operaciones y booleanos

10

Operadores de dos caracteres

11

Primera versión del REPL con tokens

Construcción del parser o analizador sintáctico

12

¿Qué es un parser y AST?

13

Estructura y definición de nodos del AST en Python

14

Parseo del programa o nodo principal

15

Parseo de assignment statements

16

Parseo de let statements

17

Parseo de errores

18

Parseo del return statement

19

Técnicas de parsing y pratt parsing

20

Pruebas del AST

21

Implementación del pratt parser

22

Parseo de Identifiers: testing

23

Parseo de Identifiers: implementación

24

Parseo de enteros

25

Prefix operators: negación y negativos

26

Infix operators y orden de las operaciones: testing

27

Infix operators y orden de las operaciones: implementación

28

Parseo de booleanos

29

Desafío: testing de infix operators y booleanos

30

Parseo de expresiones agrupadas

31

Parseo de condicionales: testing y AST

32

Parseo de condicionales: implementación

33

Parseo de declaración de funciones: testing

34

Parseo de declaración de funciones: AST e implementación

35

Parseo de llamadas a funciones: testing y AST

36

Parseo de llamadas a funciones: implementación

37

Completando los TODOs o pendientes del lexer

38

Segunda versión del REPL con AST

Evaluación o análisis semántico

39

Significado de símbolos

40

Estrategias de evaluación para intérpretes de software

41

Representación de objetos

42

Evaluación de expresiones: enteros

43

Evaluación de expresiones: booleanos y nulos

44

Evaluación de expresiones: prefix

45

Evaluación de expresiones: infix

46

Evaluación de condicionales

47

Evaluación del return statement

48

Manejo de errores

49

Ambiente

50

Bindings

51

Evaluación de funciones

52

Llamadas a funciones

Mejora del intérprete

53

Implementación de strings

54

Operaciones con strings

55

Built-in functions: objeto y tests

56

Built-in functions: evaluación

Siguientes pasos

57

Retos para expandir tu intérprete

58

Continúa con el Curso de Creación de Compiladores de Software

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Parseo del return statement

18/58
Recursos

¿Cómo parsear return statements en un parser?

El parsing de return statements es esencial para construir un lenguaje de programación funcional y semánticamente correcto. Como parte de un proceso de test-driven development, es fundamental asegurarse de que cada elemento del lenguaje se procesa correctamente. Aquí te mostramos cómo implementar parsing para return statements utilizando Python.

¿Qué se necesita para parsear un return statement?

Para poder trabajar con los return statements, es vital definir un nodo correspondiente en el Árbol de Sintaxis Abstracta (AST por sus siglas en inglés) y crear un test que verifique que los return statements se están parseando adecuadamente.

  1. Definir el Nodo para Return Statement: Un nodo en el AST define cómo se representa un statement dentro de este árbol. Al definir un return statement, debemos especificar sus características dentro del AST.

  2. Testeo de un Return Statement: Aplicamos el test-driven development, que implica definir un test antes de implementar la funcionalidad. El test debe corroborar que el parser identifica correctamente los return statements y que se añaden al AST como nodos.

¿Cómo se implementa el nodo de Return Statement?

Implementamos el nodo ReturnStatement como una clase en Python dentro del AST.

class ReturnStatement(Statement):
    def __init__(self, token: Token, return_value: Expression = None) -> None:
        super().__init__(token)
        self.return_value = return_value

    def __str__(self) -> str:
        return f"{self.token_literal()} {str(self.return_value) if self.return_value else ''};"
  • Constructor: Inicializa el nodo con un token (representación mínima de un return statement) y un valor opcional de retorno.
  • Método __str__: Determina cómo se verá el nodo cuando se convierta a cadena, útil para debugging y pruebas.

¿Cómo integrar el parsing de Return Statements dentro del parser?

Primero, necesitamos ajustar la función parse_statement para reconocer los return statements.

def parse_statement(self) -> Statement:
    if self.current_token.token_type == TokenType.RETURN:
        return self.parse_return_statement()
    ...

Después, debemos definir cómo se parsea un return statement:

def parse_return_statement(self) -> ReturnStatement:
    token = self.current_token
    self.advance_tokens()
    
    return_statement = ReturnStatement(token)

    while self.current_token.token_type != TokenType.SEMICOLON:
        self.advance_tokens()

    return return_statement
  • Token inicial: Capturamos el token actual para identificar el inicio del statement.
  • Avance hasta el punto y coma: Movemos el puntero para ignorar cualquier token intermedio hasta encontrar el final del statement (punto y coma).

Problemas comunes y depuración

Durante el desarrollo y prueba de este proceso, es usual enfrentarse a mensajes de error que indican problemas de implementación:

  • Error en la definición del nodo: Asegúrate de que las clases y métodos están bien nombrados y configurados.
  • Errores en el parsing: Los mensajes de error de tipo y atributo pueden indicar qué ajustes se necesitan para una representación correcta de los tokens y términos en el usuario.

Estas técnicas de parsing para return statements son fundamentales para el desarrollo de cualquier lenguaje de programación. Continuar perfeccionando estas implementaciones te acercará a dominar el área de desarrollo de lenguajes e intérpretes. Si necesitas más información o encuentras dificultades, revisa el código fuente y busca asistencia en la comunidad.

Aportes 1

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Estoy viendo que el LPP será un lenguaje básico 🤔 Es decir, en un return statement deberíamos poder retornar más cosas, por ejemplo, un objeto JSON (o diccionarios en el mundo de Python jaja), me pregunto cómo se hará el código para eso…
.
Yo pensaría en que en lugar de hacer el while hasta el “;” podríamos poner una función que se encargue de verificar qué expresión es la que se está retornando 🤔 Aunque siendo sinceros, aún no estamos estableciendo ningún… OHHHH A eso se refiere cuando dice que todavía no sabemos parsear expresiones jajaja, básicamente aún no estamos estableciendo ningún dato en el atributo de return_value porque aún no sabemos bien qué tipo de expresión puede estar ahí, ahora todo tiene sentido jaja