aboutsummaryrefslogtreecommitdiff
path: root/compilador/parser.py
diff options
context:
space:
mode:
Diffstat (limited to 'compilador/parser.py')
-rw-r--r--compilador/parser.py261
1 files changed, 42 insertions, 219 deletions
diff --git a/compilador/parser.py b/compilador/parser.py
index f75f817..b1fd411 100644
--- a/compilador/parser.py
+++ b/compilador/parser.py
@@ -4,231 +4,54 @@ from arbol import Arbol, Nodo
from shared import Control
from pprint import pprint
from errors import Error
+from typing import NoReturn
-valores = ['IDENT', 'BOOLEAN_LIT', 'CHAR_LIT', 'INT_LIT', 'STRING_LIT']
-
-operadores = [
- '>=', '<=', '==', '!=', '&&', '||', '++', '--',
- '=', '+', '-', '&', '|', '!', '<', '>'
-]
-
-class Selector(Enum):
- NINGUNO = 0
- DEF_VARIABLE = 1
- DIRECTIVA = 2
- EXPRESION = 3
- IF = 4
- FOR = 5
- WHILE = 6
- FUNCION = 7
+from tabla import TablaLex, Token
+from errors import Error
class Parser:
def __init__(self, input_file: str):
- self.input_file = input_file
- self.arbol = Arbol()
- self.pila_selector = [
- [Selector.NINGUNO, []] # selector, recolector
- ]
- self.pila_arbol = [self.arbol.raiz]
- self.expresion = None
self.tabla = TablaLex()
self.tabla.importar(input_file + '.tab')
-
- def inicio (self):
- for t in self.tabla.tabla:
- r = self.procesar(t)
- if r == Control.ERROR: return 1
- while r != Control.SIGUIENTE:
- r = self.procesar(t)
- if r == Control.ERROR: return 1
+ self.iterador = self.tabla.iterar()
- self.arbol.render(self.input_file + '.gv')
+ def inicio(self):
+ tok = self.want(Token.STRING_LIT, Token.BOOLEAN_LIT)
+ if type(tok) == Error:
+ print(tok.message)
+ return 1
return 0
- def procesar (self, t: LexToken):
- if len(self.pila_selector) == 0:
- return Control.SIGUIENTE
-
- pprint (self.pila_selector[-1])
-
- cima = self.pila_selector[-1]
-
- if cima[0] == Selector.NINGUNO:
- # Entrada a definición de variable (o función)
- if t.tipo in ['BOOLEAN', 'CHAR', 'INT', 'VOID']:
- self.pila_selector.pop()
- self.pila_selector.append([Selector.DEF_VARIABLE, [t]])
- return Control.SIGUIENTE
- # Entrada a directiva del lenguaje
- elif t.tipo in ['PRINT', 'READ', 'RETURN']:
- self.pila_selector.pop()
- self.pila_selector.append([Selector.DIRECTIVA, [t]])
- return Control.SIGUIENTE
- # Entrada a expresión
- elif t.tipo in valores:
- self.pila_selector.pop()
- self.pila_selector.append([Selector.EXPRESION, [t]])
- return Control.SIGUIENTE
- # Entrada a if
- elif t.tipo == 'IF':
- self.pila_selector.pop()
- self.pila_selector.append([Selector.IF, []])
- return Control.SIGUIENTE
- # Entrada a for
- elif t.tipo == 'FOR':
- self.pila_selector.pop()
- self.pila_selector.append([Selector.FOR, []])
- return Control.SIGUIENTE
- # Entrada a while
- elif t.tipo == 'WHILE':
- self.pila_selector.pop()
- self.pila_selector.append([Selector.WHILE, []])
- return Control.SIGUIENTE
-
- if cima[0] == Selector.DEF_VARIABLE:
- return self.procesar_def_variable(t)
-
- if cima[0] == Selector.DIRECTIVA:
- return self.procesar_directiva(t)
-
- if cima[0] == Selector.EXPRESION:
- return self.procesar_expresion(t)
-
- if cima[0] == Selector.IF:
- return self.procesar_if(t)
-
- if cima[0] == Selector.FOR:
- return self.procesar_for(t)
-
- if cima[0] == Selector.WHILE:
- return self.procesar_while(t)
-
- if cima[0] == Selector.FUNCION:
- return self.procesar_funcion(t)
-
- return Control.SIGUIENTE
-
- def procesar_def_variable(self, t):
- recol = self.pila_selector[-1][1]
-
- # tipo
- if len(recol) == 1:
- if t.tipo != 'IDENT':
- Error('S_ESPERA_IDENT', t.numlinea)
- return Control.ERROR
- recol.append(t)
- return Control.SIGUIENTE
-
- # tipo + ident
- if len(recol) == 2:
- if t.tipo == ';':
- self.pila_arbol[-1].hijos.append(Nodo({
- 'selector': Selector.DEF_VARIABLE,
- 'tipo': recol[0].tipo,
- 'nombre': recol[1].nombre
- }))
- self.pila_selector.pop()
- self.pila_selector.append([Selector.NINGUNO, []])
- elif t.tipo == '=':
- recol.append(t)
- else:
- Error('S_ESPERA_PC_O_IGUAL', t.numlinea)
- return Control.ERROR
- return Control.SIGUIENTE
-
- # tipo + ident + =
- if len(recol) == 3:
- if t.tipo in valores:
- self.pila_selector.append([Selector.EXPRESION, [t]])
- recol.append(t)
- else:
- Error('S_ESPERA_EXPR', t.numlinea)
- return Control.ERROR
- return Control.SIGUIENTE
-
- # tipo + ident + = + expr
- if len(recol) == 4:
- if t.tipo == ';':
- self.pila_arbol[-1].hijos.append(Nodo({
- 'selector': Selector.DEF_VARIABLE,
- 'tipo': recol[0].tipo,
- 'nombre': recol[1].nombre,
- 'valor': self.expresion
- }))
- self.expresion = None
- self.pila_selector.pop()
- self.pila_selector.append([Selector.NINGUNO, []])
- else:
- Error('S_ESPERA_PC', t.numlinea)
- return Control.ERROR
-
- return Control.SIGUIENTE
-
- def procesar_directiva(self, t):
- recol = self.pila_selector[-1][1]
-
- # directiva
- if len(recol) == 1:
- if t.tipo in valores:
- self.pila_selector.append([Selector.EXPRESION, [t]])
- recol.append(t)
- else:
- Error('S_ESPERA_EXPR', t.numlinea)
- return Control.ERROR
- return Control.SIGUIENTE
-
- # directiva + expr
- if len(recol) == 2:
- if t.tipo == ';':
- self.pila_arbol[-1].hijos.append(Nodo({
- 'selector': Selector.DIRECTIVA,
- 'expresion': self.expresion
- }))
- self.expresion = None
- self.pila_selector.pop()
- self.pila_selector.append([Selector.NINGUNO, []])
- else:
- Error('S_ESPERA_EXPR', t.numlinea)
- return Control.ERROR
-
- return Control.SIGUIENTE
-
- def procesar_expresion(self, t):
- recol = self.pila_selector[-1][1]
- tipo_ultimo = recol[-1].tipo
-
- if len(recol) == 1:
- if tipo_ultimo in valores:
- recol.append(recol[-1])
- else:
- Error('S_ESPERA_IDENT_O_LIT', t.numlinea)
- return Control.ERROR
-
- if tipo_ultimo in valores and t.tipo in operadores:
- recol.append(t)
- elif tipo_ultimo in operadores and t.tipo in valores:
- recol.append(t)
- elif tipo_ultimo in valores and t.tipo in valores:
- Error('S_ESPERA_OPER', t.numlinea)
- return Control.ERROR
- elif tipo_ultimo in operadores and t.tipo in operadores:
- Error('S_ESPERA_IDENT_O_LIT', t.numlinea)
- return Control.ERROR
- else:
- self.expresion = recol[1:]
- self.pila_selector.pop()
- return Control.REPETIR
-
- return Control.SIGUIENTE
-
- def procesar_if(self, t):
- return
-
- def procesar_for(self, t):
- return
-
- def procesar_while(self, t):
- return
-
- def procesar_funcion(self, t):
- return
+ ''' Requires the next token to have a matching ltok. Returns that
+ token, or an error. '''
+ def want(self, *want: Token) -> (Token | Error):
+ tok: LexToken = next(self.iterador)
+ if len(want) == 0:
+ return tok
+ for w in want:
+ if tok.tipo == w:
+ return tok
+ return Error(got = tok.tipo, expects = want, numlinea = tok.numlinea)
+
+ ''' Looks for a matching ltok from the lexer, and if not present,
+ unlexes the token and returns void. If found, the token is
+ consumed from the lexer and is returned. '''
+ def _try(self, *want: Token) -> (Token | NoReturn):
+ tok: LexToken = next(self.iterador)
+ if len(want) == 0:
+ return tok
+ for w in want:
+ if tok.tipo == w:
+ return tok
+ self.iterador.seek(-1)
+
+ ''' Looks for a matching ltok from the lexer, unlexes the token,
+ and returns it; or void if it was not an ltok. '''
+ def peek(self, *want: Token) -> (Token | NoReturn):
+ tok: LexToken = next(self.iterador)
+ self.iterador.seek(-1)
+ if len(want) == 0:
+ return tok
+ for w in want:
+ if tok.tipo == w:
+ return tok