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

Extensión del lexer: condicionales, operaciones y booleanos

9/58
Recursos

Aportes 4

Preguntas 2

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Reto resuelto! 😄
.
Primero escribo el test expectando los tokens:

def test_one_character_operator(self) -> None:

        source: str = "=+"
        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.ASSIGN, "="),
            Token(TokenType.PLUS, "+"),
            Token(TokenType.MINUS, "-"),
            Token(TokenType.DIVISION, "/"),
            Token(TokenType.MULTIPLICATION, "*"),
            Token(TokenType.LT, "<"),
            Token(TokenType.GT, ">"),
            Token(TokenType.NEGATION, "!"),
        ]

        self.assertEquals(tokens, expected_tokens)

Después, en la lista de token types se agregan los nuevos tokens:

DIVISION = auto()
GT = auto() # Gretater Than (>)
MINUS = auto() # Resta
MULTIPLICATION = auto()
NEGATION = auto() # Negación (!)

Después se añaden las condiciones al lexer para que pueda retornar los tokens correctos (hay que escapar la multiplicación):

        elif match(r"^-$", self._character):
            token = Token(TokenType.MINUS, self._character)

        elif match(r"^/$", self._character):
            token = Token(TokenType.DIVISION, self._character)

        elif match(r"^\*$", self._character):
            token = Token(TokenType.MULTIPLICATION, self._character)

        elif match(r"^<$", self._character):
            token = Token(TokenType.LT, self._character)

        elif match(r"^>$", self._character):
            token = Token(TokenType.GT, self._character)

        elif match(r"^!$", self._character):
            token = Token(TokenType.NEGATION, self._character)

¡Y listo! 😄
.
https://github.com/RetaxMaster/lpp/commit/b935aa10e833565492fea8935a68e4dd87067c66

Quise incluir el NOT pero lo habíamos agregado como un token inválido al inicio, entonces no fue posible y tuve que corregir.

Definición de palabras reservadas para compradores y boleanos

Este curso está muy bueno!

Aquí se me había olvidado poner los tokens en la lista y estuve media hora viendo que pasaba xd

# lexer_test.py

def test_one_character_operator(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.ASSIGN, '='),
                Token(TokenType.PLUS, '+'),
                Token(TokenType.MINUS, "-"),
                Token(TokenType.DIVISION, "/"),
                Token(TokenType.MULTIPLICATION, "*"),
                Token(TokenType.LT, "<"),
                Token(TokenType.GT, ">"),
                Token(TokenType.NEGATION, "!"),
            ]
# lexer.py

	# Token '='
        if match(r'^=$', self._character):
            token = Token(TokenType.ASSIGN, self._character)
        # Token '+'
        elif match(r'^\+$', self._character):
            token = Token(TokenType.PLUS, self._character)
        # Token '-'
        elif match(r'^-$', self._character):
            token = Token(TokenType.MINUS, self._character)
        # Token '*'
        elif match(r'^\*$', self._character):
            token = Token(TokenType.MULTIPLICATION, self._character)
        # Token '/'
        elif match(r'^\/$', self._character):
            token = Token(TokenType.DIVISION, self._character)
        # Token '<'
        elif match(r'^<$', self._character):
            token = Token(TokenType.LT, self._character)
        # Token '>'
        elif match(r'^>$', self._character):
            token = Token(TokenType.GT, self._character)
            # Token '!'
        elif match(r'^!$', self._character):
            token = Token(TokenType.NEGATION, self._character)
DIVISION = auto() # /
GT = auto() # >
MINUS = auto() # -
MULTIPLICATION = auto() # *
NEGATION = auto() # !