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
3 Hrs
11 Min
20 Seg

Parseo de declaraci贸n de funciones: testing

33/58
Resources

How are functions declared in Platzi and what elements do they use?

The declaration of functions in the Platzi programming language begins with the keyword procedure, followed by parentheses with parameters separated by commas. The body of the function is enclosed in square brackets, forming the function node. This concept is similar to languages such as C and JavaScript that use curly braces to define executable blocks. A key point is that functions can also be passed as parameters within other functions, because they are evaluable expressions.

What tests do we develop for function nodes?

To validate the correct construction of function nodes in an abstract syntax tree (AST), we perform two main tests:

  1. Node declaration: we check that the node is constructed with the necessary components, such as function body, node type, and appropriate parameters.
  2. Parameter parsing: We evaluate whether the parameters are parsed correctly, making sure that the parameter list and expressions are accurate.

Example of Test (in pseudocode):

def test_function_literal(): source = "procedure(x, y) { x + y }" lexer = Lexer(source) parser = Parser(lexer) program = parser.parse_program()    
 # Test for node type assert type(program.statements[0].expression) is Function    
 # Test for number of parameters func = program.statements[0].expression assert len(func.parameters) == 2 assert func.parameters[0].value == "x" assert func.parameters[1].value == "y"    
 # Function body test assert type(func.body.statements[0]) is InfixExpression

Implementing function nodes and their properties

When implementing the function node, we declare the parameter and body properties, using class inheritance to structure and define the internal logic. This is accomplished by extending the Expression class to form a node that is evaluated as a function.

Example code:

class Function(Expression): def __init__(self, token, parameters=None, body=None): self.token = token self.parameters = parameters if parameters else [] self.body = body    
 def __str__(self): params = ", ".join(str(p) for p in self.parameters) return f"{self.token.literal}({params}) {str(self.body)}"

What errors and solutions emerge during testing?

During initial testing, possible errors in function recognition are identified in the parser. These errors are resolved by checking the double cast functions and the correct import of classes and methods. This prepares our system to detect and correct errors early, ensuring a more robust implementation.

Scalable testing and recommendations

Achieving accurate results requires iterating through continuous testing, tweaking the code and ensuring that all possible combinations and exceptions are evaluated. I recommend:

  • Implement advanced testing to evaluate behavior in different scenarios.
  • Encourage community discussion to improve and optimize tests and solutions.

Testing should always be a central part of any development to ensure code quality. With each challenge solved, we improve not only in technical skill, but also in our problem solving ability. Keep exploring and learning!

Contributions 1

Questions 0

Sort by:

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

Algo IMPORTANTE que creo que no se le dio mucho 茅nfasis, es que dentro del test test_function_parameters, justamente cuando iniciamos el Lexer, es importante poner este comentario al lado: # type: ignore, esto porque, si no lo hacemos mypy se empezar谩 a quejar de que los tipos no son compatibles, deber铆a quedar as铆:

lexer: Lexer = Lexer(test["input"]) # type: ignore