diff options
-rw-r--r-- | lexer.py | 41 | ||||
-rw-r--r-- | main.py | 38 | ||||
-rw-r--r-- | symbol.py | 70 |
3 files changed, 149 insertions, 0 deletions
diff --git a/lexer.py b/lexer.py new file mode 100644 index 0000000..7383180 --- /dev/null +++ b/lexer.py @@ -0,0 +1,41 @@ +from enum import Enum +from symbol import LexToken, TablaLex, tokens + +t_boolean = 'booleano' +t_break = 'detener' +t_char = 'caracter' +t_double = 'doble' +t_else = 'si no' +t_for = 'por cada' +t_ident = r'[a-zA-Z_][a-zA-Z0-9_]?' +t_if = 'si' +t_int = 'entero' +t_print = 'imprimir' +t_read = 'leer' +t_return = 'retorna' +t_string = 'cadena' +t_void = 'vacio' +t_while = 'mientras' + +t_boolean_lit = r'verdadero|falso' +t_char_lit = r'\'[[:print:]]\'' +t_double_lit = r'\d+.\d+' +t_int_lit = r'\d+' +t_string_lit = r'"[[:print]]*"' + +def inicio_lexer(data): + tabla = TablaLex() + # booleano ivan = verdadero + tabla.insertar(LexToken('BOOLEAN', None, None, 1)) + tabla.insertar(LexToken('IDENT', 'ivan', None, 1)) + tabla.insertar(LexToken('=', None, None, 1)) + tabla.insertar(LexToken('BOOLEAN_LIT', None, True, 1)) + print (str(tabla)) + + ident = tabla.buscar('ivan') + print (str(ident)) + + ident.valor = True + tabla.actualizar('ivan', ident) + ident = tabla.buscar('ivan') + print (str(ident)) @@ -0,0 +1,38 @@ +import sys, getopt +from lexer import * + +def inicio (input_file, output_file): + with open(input_file) as f: + data = f.read() + inicio_lexer (data) + +def main(argv): + try: + opts, args = getopt.getopt(argv[1:], "hi:o:", ["input=", "output="]) + except getopt.GetoptError as err: + print(err) + print_help(argv[0]); + sys.exit(2) + + input_file = None + output_file = None + + for o, a in opts: + if o == "-h": + print_help (argv[0]) + elif o in ("-i", "--input"): + input_file = a + elif o in ("-o", "--output"): + output_file = a + else: + assert False, "opción desconocida" + + if input_file and output_file: + inicio (input_file, output_file) + +def print_help (arg0): + print("Uso: % s -i entrada.ñ -o salida.ñ" % arg0) + print(" % s -h" % arg0) + +if __name__ == "__main__": + main(sys.argv) diff --git a/symbol.py b/symbol.py new file mode 100644 index 0000000..c8ca424 --- /dev/null +++ b/symbol.py @@ -0,0 +1,70 @@ +from enum import Enum +from dataclasses import dataclass +from typing import Any + +reservadas = [ + 'BOOLEAN', + 'BREAK', + 'CHAR', + 'DOUBLE', + 'ELSE', + 'FOR' + 'IDENT', + 'IF', + 'INT', + 'PRINT', + 'READ', + 'RETURN', + 'STRING', + 'VOID', + 'WHILE' +] + +literales = [ + 'BOOLEAN_LIT', + 'CHAR_LIT', + 'DOUBLE_LIT', + 'INT_LIT', + 'STRING_LIT' +] + +tokens = reservadas + literales + [ + '{', '}', '(', ')', ',', '\'', + '"', ';', '=', '*', '/', '+', + '-', '>', '<', '>=', '<=', '&&', + '||', '==', '!=', '++', '--', '//' +] + +@dataclass +class LexToken: + tipo: str + nombre: str + valor: Any + numlinea: int + + def __str__(self): + return "LexToken(%s,%s,%s,%i)" % ( + self.tipo, self.nombre, self.valor, self.numlinea + ) + +class TablaLex: + def __init__(self): + self.tabla = [] + + def insertar(self, tok: LexToken): + self.tabla.append(tok) + + def buscar(self, nombre: str): + return [t for t in self.tabla if t.nombre == nombre][0] + + def actualizar(self, nombre: str, tok: LexToken): + for i, t in enumerate(self.tabla): + if t.nombre == nombre: + self.tabla[i] = tok + return + + def __str__(self): + output = "" + for t in self.tabla: + output += str(t) + "\n" + return output |