diff options
Diffstat (limited to 'compilador/parser.py')
-rw-r--r-- | compilador/parser.py | 261 |
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 |