aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compilador/astree/expr.py25
-rw-r--r--compilador/lexer.py20
-rw-r--r--compilador/parse/expr.py29
-rw-r--r--compilador/tabla.py46
-rw-r--r--pruebas/sintaxis2.es6
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