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

You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

0 Días
2 Hrs
41 Min
34 Seg

Implementación del pratt parser

21/58
Resources

What is Pratt parsing and how is it applied?

Pratt parsing is a popular top-down parsing technique, developed by the creator Pratt Baum. Through it, we iteratively build the abstract syntax tree (AST) from the beginning of the program. This technique has become well known, especially thanks to its use in important parsers such as JSON.

Pratt parsing is closely linked to the JavaScript programming language. When we work with a JSON parser in JavaScript or Python, what we do is convert a string into a data structure, for example, an object with properties.

How do you assign functions to tokens?

One of the most prominent features of Pratt parsing is that it assigns specific functions to each token. These functions can be of two types: infix (infix) or prefix (prefix). For example:

  • Prefix: The operator "not" or the prefix "-" means negation.
  • Infix: The "-" operator represents a subtraction between two numbers.

The position of the operator is critical. For example, a function call where the opening parenthesis acts as an infix operator in an expression.

How are aliased types implemented in Python?

To make our code more readable, we use aliases to identify whether we are dealing with a prefix or infix function. In Python, we can create type aliases using the typing module. Here are some examples:

from typing import Callable, Optional, Dict
 # Aliases for prefix functionsPrefixParseFunction = Callable[[], Optional['Expression']]
 # Aliases for infix functionsInfixParseFunction = Callable[[['Expression']],Optional['Expression']]
 # Dictionary for prefix functionsPrefixParseFunctions = Dict['TokenType',PrefixParseFunction]
  # Dictionary for infix functions InfixParseFunctions = Dict['TokenType', InfixParseFunction] # Dictionary for infix fun c tions InfixParseFu nctions = Dict['TokenType', InfixParseFunction] # Aliases for infix functions

How do we register parsing functions?

When initializing the parser, it is essential to register the functions to be executed for each token type. We implement lists that will allow to fill these dictionaries with the corresponding parsing functions.

class Parser: def __init__(self): self.prefix_parse_functions = self.register_prefix_functions() self.infix_parse_functions = self.register_infix_functions()
 def register_prefix_functions(self)-> PrefixParseFunctions: return {}
 def register_infix_functions(self)-> InfixParseFunctions: return {}

This forms the basic infrastructure for parsers, allowing us to later establish connections between token types and specific functions.

What are the considerations when using Pratt parsing?

Within Pratt parsing, it is crucial to keep in mind the following token using peek_token. This aspect is vital to verify if the syntactic order of the tokens is correct. The iterative process of parsing is a journey of adjustment and improvement. Initial doubts that arise will be clarified as the learning and development of the parser progresses.

Although the complexity of the subject may seem daunting, Pratt parsing provides the tools necessary to do efficient parsing. It is exciting to explore more about these techniques and how they can be applied in professional life. Join this exploration by sharing your experiences and the types of parsing you have encountered along the way - the learning never stops!

Contributions 4

Questions 1

Sort by:

Want to see more contributions, questions and answers from the community?

Buscando más tipos de parsing me tope con que básicamente solo hay dos tipos de parsing:}
.

  • Analizador sintáctico descendente (Top-Down-Parser): Un analizador puede empezar con el símbolo inicial e intentar transformarlo en la entrada, intuitivamente esto sería ir dividiendo la entrada progresivamente en partes cada vez más pequeñas, de esta forma funcionan los analizadores LL, un ejemplo es el javaCC.
  • Analizador sintáctico ascendente (Bottom-Up-Parser): Un analizador puede empezar con la entrada e intentar llegar hasta el símbolo inicial, intuitivamente el analizador intenta encontrar los símbolos más pequeños y progresivamente construir la jerarquía de símbolos hasta el inicial, los analizadores LR funcionan así y un ejemplo es el Yacc.

.
Realmente encontré muy poca información sobre el Pratt Parser, la mayoría de artículos hablan solamente de los tipos Top-Down-Parser y Bottom-Up-Parser 🤔.
.
En Wikipedia se hace una mención a los tipos Chart parser y Left corner parser, dejo aquí el enlace por si a alguien le interesa 👀:
.
Analizador sintáctico (Parser)

Qué es infix 😸, porque no tenia ni idea

En resumen forma parte de las formas de expresar una operación, estaba perdido con infix y lo demás, así que lo busque en wikipedia.
La notación infix es la que se usa en las matemáticas que nos enseñan en la escuela, las operaciónes prefix y postfix se usan para hacer evaluaciones porque son más eficientes, según wikipedia, yo no tengo ni idea 😄 si lo son.
En resumen son estos ejemplos:

  • Notación infix ➾ 3 + 3
  • Notación prefix+ 3 3
  • Notación postfix ➾ 3 3 +

Links referencias:

Notación infix: https://en.wikipedia.org/wiki/Infix_notation
Notación prefix (“Polish”): https://en.wikipedia.org/wiki/Reverse_Polish_notation
Notación postfix (“Reverse Polish”): https://en.wikipedia.org/wiki/Reverse_Polish_notation
Parser por precedencia de operador: https://en.wikipedia.org/wiki/Operator-precedence_parser

Según la RAE, la traducción de infix es infijo

Las técnicas principales que existen son Top-Down-Parser y Bottom-Up-Parser o al menos las que logré encontrar, de ahí se desglosan otro tipo de parser que se basan en esos dos