From b734388ae629930f5b9acbe3d025de21ba70512d Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Tue, 8 Nov 2022 09:50:47 -0600 Subject: Se acomoda y comenta el código MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lexer.py | 227 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 129 insertions(+), 98 deletions(-) diff --git a/lexer.py b/lexer.py index 0232645..5190a2e 100644 --- a/lexer.py +++ b/lexer.py @@ -2,13 +2,25 @@ from enum import Enum from symbol import LexToken, TablaLex, tokens op_compuestos = ['>=', '<=', '==', '!=', '&&', '||', '++', '--'] -op_simples_a = ['=', '+', '-', '&', '|'] -op_simples_b = ['!', '<', '>'] +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 +class Selector(Enum): + NINGUNO = 0 + STRING_LIT = 1 + CHAR_LIT = 2 + ID_RESERVADA = 3 + COMMENT = 4 + +class Control(Enum): + SIGUIENTE = 0 + REPETIR = 1 + ERROR = 2 + class Lexer: tabla = TablaLex() - selector = '' + selector = Selector.NINGUNO recol_string = '' recol_caracter = '' recol_comentario = '' @@ -17,52 +29,54 @@ class Lexer: def inicio_lexer(self, data): for c in data + "\n": - r = self.procesar_caracter(c) + r = self.procesar(c) if r == 2: return - while r != 0: + while r != Control.SIGUIENTE: print ('r = ' + str(r)) - r = self.procesar_caracter(c) - if r == 2: return + r = self.procesar(c) + if r == Control.ERROR: return # Imprimir tabla de símbolos print (str(self.tabla)) - # c => caracter - # return 0 => siguiente caracter - # return 1 => repetir caracter - # return 2 => error - def procesar_caracter(self, c): + def procesar(self, c): if c != "\t" and c != "\n": - print (c + ' (' + self.selector + ')') + print (c + ' (' + str(self.selector) + ')') - if self.selector == '': - # Entradas a tokens + if self.selector == Selector.NINGUNO: + # Entrada a string if c == '"': - self.selector = 'STRING_LIT' - return 0 + self.selector = Selector.STRING_LIT + return Control.SIGUIENTE + # Entrada a caracter elif c == '\'': - self.selector = 'CHAR_LIT' - return 0 + self.selector = Selector.CHAR_LIT + return Control.SIGUIENTE + # Entrada a id o palabra reservada elif c.isalpha() or c == '_': - self.selector = 'ID/RESERVADA' + self.selector = Selector.ID_RESERVADA + # Entrada a comentario elif c == '/': self.recol_comentario = '/' + # Entrada a operador (simple o compuesto) elif c in op_simples_a and self.recol_operador == '': self.recol_operador = c - return 0 + return Control.SIGUIENTE + # Entrada a operador (simple) elif c in op_simples_b: self.recol_operador = c - return 0 + return Control.SIGUIENTE + # Entrada a tokens simples elif (c == '{' or c == '}' or c == '(' or c == ')' or c == ',' or c == '.' or c == ';' or (c == '*' and self.recol_comentario == '')): self.tabla.insertar(LexToken(c, None, None, 1)) - return 0 + return Control.SIGUIENTE # Apertura de comentario if self.recol_comentario == '/' and c == '*': - self.selector = 'COMMENT' + self.selector = Selector.COMMENT self.recol_comentario = '' - return 0 + return Control.SIGUIENTE # Apertura de operador compuesto if len(self.recol_operador) > 0: @@ -71,90 +85,107 @@ class Lexer: # Operador compuesto self.tabla.insertar(LexToken(rc, None, None, 1)) self.recol_operador = '' - return 0 + return Control.SIGUIENTE else: # Operador simple self.tabla.insertar(LexToken(self.recol_operador, None, None, 1)) if c in op_simples: self.tabla.insertar(LexToken(c, None, None, 1)) self.recol_operador = '' - return 0 + return Control.SIGUIENTE # Cadenas de texto - if self.selector == 'STRING_LIT': - if c == '"': - self.tabla.insertar(LexToken('STRING_LIT', None, self.recol_string, 1)) - self.selector = '' - self.recol_string = '' - else: - self.recol_string += c - + if self.selector == Selector.STRING_LIT: + return self.procesar_cadena(c) + # Caracteres - if self.selector == 'CHAR_LIT': - if len(self.recol_caracter) > 1: - print ('Error: más de un caracter en una literal de caracter') - return 2 - if c == '\'': - if len(self.recol_caracter) == 0: - print ('Error: literal de caracter vacía') - return 2 - self.tabla.insertar(LexToken('CHAR_LIT', None, self.recol_caracter, 1)) - self.selector = '' - self.recol_caracter = '' - else: - self.recol_caracter += c + if self.selector == Selector.CHAR_LIT: + return self.procesar_caracter(c) # Comentarios - if self.selector == 'COMMENT': - if c == '*': - self.recol_comentario = c - elif self.recol_comentario == '*': - if c == '/': - self.selector = '' - self.recol_comentario = '' - else: - self.recol_comentario = '' + if self.selector == Selector.COMMENT: + return self.procesar_comentario(c) # Identificador o palabra reservada - if self.selector == 'ID/RESERVADA': - if c.isalnum() or c == '_': - self.recol_ident += c + if self.selector == Selector.ID_RESERVADA: + return self.procesar_identificador(c) + + return Control.SIGUIENTE + + def procesar_cadena(self, c): + if c == '"': + self.tabla.insertar(LexToken('STRING_LIT', None, self.recol_string, 1)) + self.selector = Selector.NINGUNO + self.recol_string = '' + else: + self.recol_string += c + return Control.SIGUIENTE + + def procesar_caracter(self, c): + if len(self.recol_caracter) > 1: + print ('Error: más de un caracter en una literal de caracter') + return Control.ERROR + if c == '\'': + if len(self.recol_caracter) == 0: + print ('Error: literal de caracter vacía') + return Control.ERROR + self.tabla.insertar(LexToken('CHAR_LIT', None, self.recol_caracter, 1)) + self.selector = Selector.NINGUNO + self.recol_caracter = '' + else: + self.recol_caracter += c + return Control.SIGUIENTE + + def procesar_comentario(self, c): + if c == '*': + self.recol_comentario = c + elif self.recol_comentario == '*': + if c == '/': + self.selector = Selector.NINGUNO + self.recol_comentario = '' else: - if self.recol_ident == 'booleano': - self.tabla.insertar(LexToken('BOOLEAN', None, None, 1)) - elif self.recol_ident == 'detener': - self.tabla.insertar(LexToken('BREAK', None, None, 1)) - elif self.recol_ident == 'byte': - self.tabla.insertar(LexToken('BYTE', None, None, 1)) - elif self.recol_ident == 'caracter': - self.tabla.insertar(LexToken('CHAR', None, None, 1)) - elif self.recol_ident == 'doble': - self.tabla.insertar(LexToken('DOUBLE', None, None, 1)) - elif self.recol_ident == 'sino': - self.tabla.insertar(LexToken('ELSE', None, None, 1)) - elif self.recol_ident == 'porcada': - self.tabla.insertar(LexToken('FOR', None, None, 1)) - elif self.recol_ident == 'si': - self.tabla.insertar(LexToken('IF', None, None, 1)) - elif self.recol_ident == 'entero': - self.tabla.insertar(LexToken('INT', None, None, 1)) - elif self.recol_ident == 'imprimir': - self.tabla.insertar(LexToken('PRINT', None, None, 1)) - elif self.recol_ident == 'leer': - self.tabla.insertar(LexToken('READ', None, None, 1)) - elif self.recol_ident == 'retorna': - self.tabla.insertar(LexToken('RETURN', None, None, 1)) - elif self.recol_ident == 'vacio': - self.tabla.insertar(LexToken('VOID', None, None, 1)) - elif self.recol_ident == 'mientras': - self.tabla.insertar(LexToken('WHILE', None, None, 1)) - elif self.recol_ident == 'verdadero': - self.tabla.insertar(LexToken('BOOLEAN_LIT', None, True, 1)) - elif self.recol_ident == 'falso': - self.tabla.insertar(LexToken('BOOLEAN_LIT', None, False, 1)) - else: - self.tabla.insertar(LexToken('IDENT', self.recol_ident, None, 1)) - self.recol_ident = '' - self.selector = '' - return 1 - return 0 + self.recol_comentario = '' + return Control.SIGUIENTE + + def procesar_identificador(self, c): + if c.isalnum() or c == '_': + self.recol_ident += c + else: + if self.recol_ident == 'booleano': + self.tabla.insertar(LexToken('BOOLEAN', None, None, 1)) + elif self.recol_ident == 'detener': + self.tabla.insertar(LexToken('BREAK', None, None, 1)) + elif self.recol_ident == 'byte': + self.tabla.insertar(LexToken('BYTE', None, None, 1)) + elif self.recol_ident == 'caracter': + self.tabla.insertar(LexToken('CHAR', None, None, 1)) + elif self.recol_ident == 'doble': + self.tabla.insertar(LexToken('DOUBLE', None, None, 1)) + elif self.recol_ident == 'sino': + self.tabla.insertar(LexToken('ELSE', None, None, 1)) + elif self.recol_ident == 'porcada': + self.tabla.insertar(LexToken('FOR', None, None, 1)) + elif self.recol_ident == 'si': + self.tabla.insertar(LexToken('IF', None, None, 1)) + elif self.recol_ident == 'entero': + self.tabla.insertar(LexToken('INT', None, None, 1)) + elif self.recol_ident == 'imprimir': + self.tabla.insertar(LexToken('PRINT', None, None, 1)) + elif self.recol_ident == 'leer': + self.tabla.insertar(LexToken('READ', None, None, 1)) + elif self.recol_ident == 'retorna': + self.tabla.insertar(LexToken('RETURN', None, None, 1)) + elif self.recol_ident == 'vacio': + self.tabla.insertar(LexToken('VOID', None, None, 1)) + elif self.recol_ident == 'mientras': + self.tabla.insertar(LexToken('WHILE', None, None, 1)) + elif self.recol_ident == 'verdadero': + self.tabla.insertar(LexToken('BOOLEAN_LIT', None, True, 1)) + elif self.recol_ident == 'falso': + self.tabla.insertar(LexToken('BOOLEAN_LIT', None, False, 1)) + else: + self.tabla.insertar(LexToken('IDENT', self.recol_ident, None, 1)) + self.recol_ident = '' + self.selector = Selector.NINGUNO + return Control.REPETIR + return Control.SIGUIENTE -- cgit v1.2.3