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

Lectura de caracteres y tokens

5/58
Recursos

Aportes 8

Preguntas 4

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

Efectivamente los errores fueron mis amigos jaja, tuve otros errores porque hab铆a escrito mal una sintaxis en Python, y me dec铆a: 鈥淓rror en la l铆nea X鈥 y fui a ver la l铆nea X y as铆 encontr茅 mis errores 馃槃
.
Apenas estamos iniciando pero ando con hype jajaja, me gusta el TDD. Por cierto, algo curioso es que, por la forma en la que se leen los tokens ilegales, el orden en el que los comparamos en el expected_tokens debe ser el mismo que el orden en el que pusimos los tokens en source, de lo contrario el assert fallar谩 aunque los tokens s铆 sean ilegales simplemente por el orden

A m铆 los test no me fallaban, solo me dec铆a Ran 0 tests in 0.007s (se corrieron cero pruebas en 0.007 segundos) y al final lo solucion茅 usando el comando:

mypy . && py -m unittest discover  -p "*_test.py"

en vez de

mypy . && nosetests

A ver, entendamos lo que tenemos por ac谩:

def test_ilegal(self) -> None:
        source: str = '!驴@'
        lexer: Lexer = Lexer(source)
        tokens: List[Token] = []

        for i in range(len(source)):
            tokens.append(lexer.next_token())

        expected_tokens: List[Token] = [
            Token(TokenType.ILLEGAL, '!'),
            Token(TokenType.ILLEGAL, '驴'),
            Token(TokenType.ILLEGAL, '@')
        ]

        self.assertEquals(tokens, expected_tokens)

Aqu铆 tenemos un test en el que estamos cargando una lista con caracteres inv谩lidos para nuestro lenguaje. Luego de esto creamos una lista de los tokens esperados, en este caso queremos que el Lexer devuelva que los tres caracteres son ilegales como TokenType.ILLEGAL Para hacer esto alimentamos el lexer con la l铆nea de texto que contiene los caracteres ilegales. Esta l铆nea es revisada por el lexer en next_token Method validando que el car谩cter sea ilegal y devolviendo un TokenType.ILLEGAL Sin embargo, debemos notar que en este punto el Lexer siempre va a devolver Token.ILLEGAL para lo que sea que lea, podemos meterle cualquier car谩cter alfanum茅rico que siempre va a devolver Token.ILLEGAL ya que a煤n no estamos haciendo ninguna validaci贸n.

def next_token(self) -> Token:
        token = Token(TokenType.ILLEGAL, self._character)
        self._read_character()
        return token

En el m茅todo next_token devolvemos siempre Tokens Ilegales por cada car谩cter recibido en la l铆nea.

def _read_character(self) -> None:
        if self._read_position >= len(self._source):
            self._character = ''
        else:
            self._character = self._source[self._read_position]
        self._position = self._read_position
        self._read_position += 1

Solamente est谩 moviendo la lectura un car谩cter hacia adelante de la lista recibida en la l铆nea de texto.

  • Rescatamos ac谩 un par de cosas, los Lexer van a moverse linea a linea por cada archivo de c贸digo fuente.

  • Los token nos van a permitir usar los Enum para identificar el tipo de elemento que tenemos en cada l铆nea

  • Tendremos que encontrar una forma de pasear o validar palabras m谩s all谩 de caracteres simples, es como ve铆amos en la clase pasada lo que haremos con los espacios en blanco.

Para aquellos que 鈥渘osetests鈥 les de alg煤n error como 鈥楢ttributeError鈥, es porque 鈥渘ose鈥 ya no es mantenido, yo he instalado nose2. Lo usar铆an as铆

mypy . && nose2

Tip: Desde python 3.9 es posible utilizar list[Token] para no tener que importar List desde typing.

Muy cool el TDD!!!

Nota mental, para que los tests corran hay que estar en la carpeta ra铆z que contiene la carpeta lpp. De lo contrario se muestra un error como este:

. is not a valid Python package name

Tengo que darle un par de vueltas m谩s. Complicado el tema