diff options
-rw-r--r-- | compilador/astree/expr.py | 25 | ||||
-rw-r--r-- | compilador/lexer.py | 20 | ||||
-rw-r--r-- | compilador/parse/expr.py | 29 | ||||
-rw-r--r-- | compilador/tabla.py | 46 | ||||
-rw-r--r-- | pruebas/sintaxis2.es | 6 |
5 files changed, 81 insertions, 45 deletions
diff --git a/compilador/astree/expr.py b/compilador/astree/expr.py index c074553..527e606 100644 --- a/compilador/astree/expr.py +++ b/compilador/astree/expr.py @@ -49,6 +49,13 @@ class BinarithmExpr: lvalue: Expr rvalue: Expr +# A break expression. +# +# detener +@dataclass +class BreakExpr: + pass + # A function call expression. # # foo(bar) @@ -68,6 +75,13 @@ class CallExpr: class CompoundExpr: exprs: List[Expr] +# A continue expression. +# +# continuar +@dataclass +class ContinueExpr: + pass + # A scalar value. Value = bool | str | int | type(None) @@ -115,7 +129,9 @@ class ReadExpr: # A return statement. # # retorna a -ReturnExpr = Optional[Expr] +@dataclass +class ReturnExpr: + expr: Optional[Expr] # A while expression. # @@ -126,6 +142,7 @@ class WhileExpr: body: Expr # A Javañol expression. -Expr = (AccessExpr | AssignExpr | BinarithmExpr | CallExpr | - ConstantExpr | ForExpr | IfExpr | CompoundExpr | - PrintExpr | ReadExpr | ReturnExpr) +Expr = (AccessExpr | AssignExpr | BinarithmExpr | BreakExpr | + CallExpr | ConstantExpr | ContinueExpr | ForExpr | + IfExpr | CompoundExpr | PrintExpr | ReadExpr | + ReturnExpr) diff --git a/compilador/lexer.py b/compilador/lexer.py index feac970..4d97b9d 100644 --- a/compilador/lexer.py +++ b/compilador/lexer.py @@ -1,5 +1,5 @@ from enum import Enum -from tabla import LexToken, TablaLex, Token, tokens +from tabla import LexToken, TablaLex, Token, tokens, reservadas from parser import Parser from shared import Control from errors import Error @@ -9,22 +9,6 @@ op_simples_a = ['=', '+', '-', '&', '|'] # pueden ir al final del op compuesto op_simples_b = ['!', '<', '>'] # solo pueden ir al inicio del op compuesto op_simples = op_simples_a + op_simples_b otros_tokens = ['{', '}', '(', ')', ',', '.', ';'] -reservadas = { - 'booleano': 'BOOLEAN', - 'detener': 'BREAK', - 'cadena': 'STRING', - 'caracter': 'CHAR', - 'sino': 'ELSE', - 'porcada': 'FOR', - 'si': 'IF', - 'entero': 'INT', - 'imprimir': 'PRINT', - 'leer': 'READ', - 'retorna': 'RETURN', - 'vacio': 'VOID', - 'mientras': 'WHILE', - 'funcion': 'FUNCTION' -} class Selector(Enum): NINGUNO = 0 @@ -186,7 +170,7 @@ class Lexer: if c.isalnum() or c == '_': self.recol_ident += c else: - if self.recol_ident in reservadas.keys(): + if self.recol_ident in reservadas: self.insertar_tabla(Token(self.recol_ident), None, None) elif self.recol_ident == 'verdadero': self.insertar_tabla(Token.BOOLEAN_LIT, None, True) diff --git a/compilador/parse/expr.py b/compilador/parse/expr.py index 14fcf0c..6608f6a 100644 --- a/compilador/parse/expr.py +++ b/compilador/parse/expr.py @@ -4,7 +4,7 @@ from tabla import Token, LexToken from parse.base import BaseParser from parse.ident import ParseIdent from errors import Error -from astree.expr import Expr, BinarithmOp, ConstantExpr, NumberConstant, CallExpr, PrintExpr, BinarithmExpr, CompoundExpr, ReadExpr, AccessExpr, AssignExpr, IfExpr, WhileExpr +from astree.expr import * class ParseExpr: def __init__(self, parser: BaseParser): @@ -12,11 +12,14 @@ class ParseExpr: def expr(self) -> (Expr | Error): obj = None - tok = self.parser.peek(Token.IF, Token.WHILE) + tok = self.parser.peek(Token.IF, Token.BREAK, Token.CONTINUE, + Token.RETURN, Token.WHILE) if not tok: obj = self.binarithm(None, 0) elif tok.tipo == Token.IF: obj = self.if_expr() + elif tok.tipo in [Token.BREAK, Token.CONTINUE, Token.RETURN]: + obj = self.control() elif tok.tipo == Token.WHILE: obj = self.while_expr() @@ -143,6 +146,28 @@ class ParseExpr: return Error(msg = "Se esperaba una constante.", numlinea = tok.numlinea) return expr + def control(self) -> (Expr | Error): + tok = self.parser.want(Token.BREAK, Token.CONTINUE, Token.RETURN) + if type(tok) is Error: + return tok + + expr = None + if tok.tipo == Token.BREAK: + expr = BreakExpr() + elif tok.tipo == Token.CONTINUE: + expr = ContinueExpr() + elif tok.tipo == Token.RETURN: + tok = self.parser.peek(Token.COMMA, Token.SEMICOLON, Token.EOF) + if not tok: + _expr = self.expr() + if type(_expr) is Error: + return _expr + expr = ReturnExpr(expr = _expr) + else: + expr = ReturnExpr(expr = None) + + return expr + def builtin(self) -> (Expr | Error): tok: LexToken = self.parser.peek(Token.PRINT, Token.READ) if not tok: diff --git a/compilador/tabla.py b/compilador/tabla.py index fb76e08..7871a42 100644 --- a/compilador/tabla.py +++ b/compilador/tabla.py @@ -7,20 +7,20 @@ from typing import Any from nanoiter import NanoIter reservadas = [ - 'BOOLEAN', - 'CHAR', - 'DOUBLE', - 'ELSE', - 'IDENT', - 'IF', - 'INT', - 'PRINT', - 'READ', - 'RETURN', - 'STRING', - 'VOID', - 'WHILE', - 'FUNCTION' + 'booleano', + 'cadena', + 'caracter', + 'continuar', + 'detener', + 'entero', + 'funcion', + 'imprimir', + 'leer', + 'mientras', + 'retornar', + 'si', + 'sino', + 'vacio', ] literales = [ @@ -31,6 +31,13 @@ literales = [ 'STRING_LIT' ] +tokens = reservadas + literales + [ + '{', '}', '(', ')', ',', '\'', + '"', ';', '=', '*', '/', '+', + '-', '>', '<', '>=', '<=', '&&', + '||', '==', '!=' +] + class Token(Enum): BOOLEAN = 'booleano' CHAR = 'caracter' @@ -41,7 +48,9 @@ class Token(Enum): INT = 'entero' PRINT = 'imprimir' READ = 'leer' - RETURN = 'retorna' + BREAK = 'detener' + CONTINUE = 'continuar' + RETURN = 'retornar' STRING = 'cadena' VOID = 'vacio' FUNCTION = 'funcion' @@ -73,12 +82,7 @@ class Token(Enum): NOTEQ = '!=' EOF = 'EOF' -tokens = reservadas + literales + [ - '{', '}', '(', ')', ',', '\'', - '"', ';', '=', '*', '/', '+', - '-', '>', '<', '>=', '<=', '&&', - '||', '==', '!=' -] + @dataclass class LexToken: diff --git a/pruebas/sintaxis2.es b/pruebas/sintaxis2.es index c8cbb59..09e5f1f 100644 --- a/pruebas/sintaxis2.es +++ b/pruebas/sintaxis2.es @@ -9,11 +9,17 @@ funcion entero a (entero a, cadena b) { imprimir (b + 20); } sino b; leer d; + retornar 10 + 20; }; funcion caracter b (booleano a) { imprimir ("Adiós"); mientras (a < 10) { imprimir ("Hola"); + si (a >= 10) { + continuar; + } sino detener; + a = a + 1; }; leer x; + retornar; };
\ No newline at end of file |