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 de declaración de funciones: AST e implementación

34/58
Recursos

¿Cómo se genera la función parse function en un AST?

En el desarrollo de un compilador, generar un Árbol de Sintaxis Abstracta o AST es esencial para procesar el código adecuadamente. Aquí aprenderemos cómo se genera específicamente la función parse function, que es vital para interpretar correctamente las funciones dentro de un lenguaje de programación.

Para iniciar, debemos asegurarnos de que el nodo de la función esté correctamente identificado en el AST. Esto implica:

  • Importar el nodo función dentro del AST.
  • Insertar la función parse function en su lugar correcto, acorde al orden alfabético. Es fundamental ordenar adecuadamente el código para mantener su legibilidad.
# Se define la función parse function
def parse_function():
    # Verifica que el current token no sea none
    if current_token is None:
        return None
    
    # Inicializa el nodo de función
    function_node = FunctionNode(current_token)
    # Más lógica implementada aquí...

¿Cómo se validan los tokens al construir el árbol de sintaxis?

La sintaxis siempre debe ser precisa; de otro modo, no podremos continuar con el análisis. Para asegurar esto, revisamos que el token actual no sea None y que contenga la información adecuada.

  • Se anticipa la apertura de un paréntesis izquierdo después de identificar la palabra clave de la función.
  • De no estar presente, se termina el proceso de parsing inmediatamente.
# Verificación del paréntesis izquierdo y pase de tokens incorrecto
if not expected_token(TokenType.LEFT_PAREN):
    return None

¿Cómo se definen y parsean los parámetros de una función?

Los parámetros son elementos cruciales dentro de una función. Aquí se detalla el proceso para definir y parsear estos parámetros:

  1. Crear y inicializar una lista vacía llamada params.
  2. Utilizar una función auxiliar parse_function_parameters para identificar los parámetros.
  3. Comprobación de tokens para determinar si existen parámetros o si la lista estará vacía.
def parse_function_parameters():
    params = []
    # Lógica para identificar y añadir parámetros
  • Si el pickToken es un paréntesis derecho, se concluye que no hay parámetros.
  • Si hay parámetros, se generan como identificadores separados por comas.

¿Cómo se maneja el cuerpo de funciones en un AST?

Una vez que los parámetros están claros, se avanza hacia el cuerpo de la función. Para esto:

  • Se abre un corchete izquierdo y se parsea el bloque de comandos.
  • Finalmente, se emplea una función existente para interpretar este bloque y se retorna el nodo de la función.
# Proceso de validación para el corchete izquierdo
if not expected_token(TokenType.LEFT_BRACE):
    return None

# Reutilización de lógica para parsear el bloque de la función
block_node = parse_block()
return function_node

¿Cómo se registra una nueva función como prefijo en un parser?

El último paso para consolidar la integración dentro del parser es registrar la función como un prefijo. Esto se ejecuta vinculándola correctamente con el tipo de token de función.

  • Modificar la función register_prefix para incluir el token de función.
  • Asegurarse de que el código cubra adecuadamente la secuencia FGHI del AST.
# Registro en el parser
register_prefix(TokenType.FUNCTION, parse_function)

Este flujo muestra un enfoque detallado para el desarrollo de parsers en lenguajes de programación, un proceso que exige atención y práctica, clave dentro del test-driven development. Al escribir tests y corregir errores, se garantiza la validez del código, proporcionando una base sólida para la implementación futura de funciones adicionales.

Continúa expandiendo tus conocimientos en programación, ajustando y mejorando tu flujo de desarrollo mediante el aprendizaje continuo. Enfrentarás desafíos, pero ellos fortalecerán tu habilidad para comprender procesos complejos en el desarrollo de software.

Aportes 3

Preguntas 0

Ordenar por:

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

Me encanta cómo David transmite el amor por el Test Driven Development jaja, aunque la función _parse_function está mal colocada alfabéticamente 👀.
.
Por todo lo demás todo correcto 😄 Me encanta porque es como ir programando un robotito y decirle: “Ok, ahora vas a hacer eso, avanza tantos tokens, agarra el siguiente token, compara si es el token que espero” y así jaja, ya quiero terminar el LPP 👀

Cuando parseamos estamos construyendo el AST pero también estamos checando la sintaxis.

había hecho que las funciones también se puedan declarar con nombres e iba a enviar como lo hice, pero cuando le di enviar me salió un error que decía que había puesto enlaces inválidos o algo así cuando no había puesto ningún enlace a ningún lado, solo los bloques de código