def evaluarFuncion(self,ctx): simbolo = self.tablaDeSimbolosActual.resolver(ctx.NAME()) if simbolo == None: ln = -1 self.raiseError(ln, 'Error en el simbolo', ctx.NAME()) if simbolo.tipo != "FUNCION": ln = -1 self.raiseError(ln,'Error, el simbolo no puede ser evaluado como una funcion',ctx.NAME()) parametros = [] if ctx.parameters() != None : parametros.append(ctx.parameters().test()) if len( ctx.parameters().sub_parameters() ) > 0: for param in ctx.parameters().sub_parameters(): parametros.append(param.test()) if len(parametros) != len(simbolo.argumentos ): ln = -1 self.raiseError(ln, "Error en la cantidad de parametros", ctx.NAME()) nuevaTablaSimbolos = TablaSimbolos(None,self.tablaDeSimbolosActual.contexto+1) for i in xrange(0,len(parametros)): argument = self.evaluarArgumento(parametros[i]) #print("argumento: "+str(argument)) simboloNuevo = Simbolo(simbolo.argumentos[i],argument[0],argument[1]) nuevaTablaSimbolos.agregarSimbolo(simbolo.argumentos[i], simboloNuevo) nuevaTablaSimbolos.padre = self.tablaDeSimbolosActual self.tablaDeSimbolosActual = nuevaTablaSimbolos ret = super(GramaticaExtVisitor,self).visit(simbolo.valor) self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla() print("Evaluando: "+str(ctx.NAME())+" con valor de retorno "+str(ret)) if ret != self._NONE: return ret; return self._NONE
def visitIterable_filter(self, ctx): iterab = super(GramaticaExtVisitor, self).visit(ctx.iterable()) if iterab == None: ln = -1 self.raiseError(ln, 'Error al evaluar el iterador', "iterator-eval") if iterab.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El objeto especificado no es de tipo iterable', "iterable-expected") if iterab.subtipo == "TUPLE": ln = -1 self.raiseError( ln, 'No es posible realizar un recorrido sobre una tupla', "iterable-tuple") filtrada = None if iterab.subtipo == "LIST": filtrada = [] else: filtrada = {} self.tablaDeSimbolosActual = TablaSimbolos( self.tablaDeSimbolosActual, self.tablaDeSimbolosActual.contexto) for tmp in iterab.valor: ac = None ty = None if iterab.subtipo == "LIST": ac = tmp.valor ty = tmp.tipo else: ac = iterab.valor[tmp].valor ty = iterab.valor[tmp].tipo simbolo = Simbolo(ctx.lambda_test().NAME(), ty, ac) self.tablaDeSimbolosActual.agregarSimbolo(simbolo.nombre, simbolo) res = super(GramaticaExtVisitor, self).visit(ctx.lambda_test().test()) if res.tipo != "BOOL": ln = -1 self.raiseError( ln, 'No es posible filtrar bajo la funcion especificada', "lambda-filter-error") if res.valor == True and iterab.subtipo == "LIST": filtrada.append(tmp) elif res.valor == True and iterab.subtipo == "MAP": filtrada[tmp] = iterab.valor[tmp] self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla() nodo = Nodo() nodo.subtipo = iterab.subtipo nodo.tipo = "ITERATOR" nodo.valor = filtrada print(nodo) return nodo
def evaluarFuncion(self, ctx): simbolo = self.tablaDeSimbolosActual.resolver(ctx.NAME()) if simbolo == None: ln = -1 self.raiseError(ln, 'Error en el simbolo', ctx.NAME()) if simbolo.tipo != "FUNCION": ln = -1 self.raiseError( ln, 'Error, el simbolo no puede ser evaluado como una funcion', ctx.NAME()) parametros = [] if ctx.parameters() != None: parametros.append(ctx.parameters().test()) if len(ctx.parameters().sub_parameters()) > 0: for param in ctx.parameters().sub_parameters(): parametros.append(param.test()) if len(parametros) != len(simbolo.argumentos): ln = -1 self.raiseError(ln, "Error en la cantidad de parametros", ctx.NAME()) nuevaTablaSimbolos = TablaSimbolos( None, self.tablaDeSimbolosActual.contexto + 1) for i in xrange(0, len(parametros)): argument = self.evaluarArgumento(parametros[i]) #print("argumento: "+str(argument)) simboloNuevo = Simbolo(simbolo.argumentos[i], argument[0], argument[1]) nuevaTablaSimbolos.agregarSimbolo(simbolo.argumentos[i], simboloNuevo) nuevaTablaSimbolos.padre = self.tablaDeSimbolosActual self.tablaDeSimbolosActual = nuevaTablaSimbolos ret = super(GramaticaExtVisitor, self).visit(simbolo.valor) self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla() print("Evaluando: " + str(ctx.NAME()) + " con valor de retorno " + str(ret)) if ret != self._NONE: return ret return self._NONE
def visitFor_stmt(self, ctx): nm = ctx.NAME() iterab = super(GramaticaExtVisitor, self).visit(ctx.iterable()) if iterab == None: ln = -1 self.raiseError(ln, 'No es posible obtener el iterable', "iterable-gen") elif iterab.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El simbolo no es iterable', "iterable-expected") elif iterab.subtipo == "TUPLE": ln = -1 self.raiseError( ln, 'No es posible realizar un recorrido sobre una tupla', "iterable-tuple") self.tablaDeSimbolosActual = TablaSimbolos( self.tablaDeSimbolosActual, self.tablaDeSimbolosActual.contexto) self.tablaDeSimbolosActual.agregarSimbolo(nm, Simbolo(nm, None, None)) for tmp in iterab.valor: self.tablaDeSimbolosActual.agregarSimbolo( nm, Simbolo(nm, tmp.tipo, tmp.valor)) self.evaluarInstrucciones(ctx.stmt()) self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla()
def visitFor_stmt(self, ctx): nm = ctx.NAME() iterab = super(GramaticaExtVisitor,self).visit(ctx.iterable()) if iterab == None: ln = -1 self.raiseError(ln, 'No es posible obtener el iterable', "iterable-gen") elif iterab.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El simbolo no es iterable', "iterable-expected") elif iterab.subtipo == "TUPLE": ln = -1 self.raiseError(ln, 'No es posible realizar un recorrido sobre una tupla', "iterable-tuple") self.tablaDeSimbolosActual = TablaSimbolos(self.tablaDeSimbolosActual,self.tablaDeSimbolosActual.contexto) self.tablaDeSimbolosActual.agregarSimbolo(nm,Simbolo(nm,None,None)) for tmp in iterab.valor: self.tablaDeSimbolosActual.agregarSimbolo(nm,Simbolo(nm,tmp.tipo,tmp.valor)) self.evaluarInstrucciones(ctx.stmt()) self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla()
def visitIterable_filter(self, ctx): iterab = super(GramaticaExtVisitor,self).visit(ctx.iterable()) if iterab == None: ln = -1 self.raiseError(ln, 'Error al evaluar el iterador', "iterator-eval") if iterab.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El objeto especificado no es de tipo iterable', "iterable-expected") if iterab.subtipo == "TUPLE": ln = -1 self.raiseError(ln, 'No es posible realizar un recorrido sobre una tupla', "iterable-tuple") filtrada = None if iterab.subtipo == "LIST": filtrada = [] else: filtrada = {} self.tablaDeSimbolosActual = TablaSimbolos(self.tablaDeSimbolosActual,self.tablaDeSimbolosActual.contexto) for tmp in iterab.valor: ac = None ty = None if iterab.subtipo == "LIST": ac = tmp.valor ty = tmp.tipo else: ac = iterab.valor[tmp].valor ty = iterab.valor[tmp].tipo simbolo = Simbolo(ctx.lambda_test().NAME(),ty,ac) self.tablaDeSimbolosActual.agregarSimbolo(simbolo.nombre, simbolo) res = super(GramaticaExtVisitor,self).visit(ctx.lambda_test().test()) if res.tipo != "BOOL": ln = -1 self.raiseError(ln, 'No es posible filtrar bajo la funcion especificada', "lambda-filter-error") if res.valor == True and iterab.subtipo == "LIST": filtrada.append(tmp) elif res.valor == True and iterab.subtipo =="MAP": filtrada[tmp] = iterab.valor[tmp] self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla() nodo = Nodo() nodo.subtipo = iterab.subtipo nodo.tipo = "ITERATOR" nodo.valor = filtrada print(nodo) return nodo
def ejecutar_analisis(self): #self.consola.setText("****** Preparando Analisis ******") self.consola.clear() indextab = self.editores.tabText(self.editores.currentIndex()) ##self.consola.setText("Archivo a analizar: "+indextab) tab = self.editores.widget(self.editores.currentIndex()) items = tab.children() codigo = items[0].toPlainText() ast = None analisis_semantico = False lst = [] print( "___________INICIA PROCESO DE ANALISIS LEXICO Y SINTACTICO_______________" ) try: if self.analizador_cambiado: gramaticaD.lst_errores = [] ast = gramaticaD.parse(codigo) arbolparser = GramaticaDG.parse(codigo) graficaAST = GraficarArbol(args=(arbolparser, "ASPDescendente"), daemon=True) graficaAST.start() graficaGramatical = GraficarGramatica( args=(gramaticaD.lstGrmaticales, "ReporteGramatical"), daemon=True) graficaGramatical.start() lst = gramaticaD.lst_errores gramaticaD.lstGrmaticales = [] else: gramatica.lst_errores = [] ast2 = gramatica.parse(codigo) ast = ast2.instruccion graficaAST = GraficarArbol(args=(ast2.nodo, "ASPAscendente"), daemon=True) graficaAST.start() graficaGramatical = GraficarGramatica( args=(gramatica.lstGrmaticales, "ReporteGramatical"), daemon=True) graficaGramatical.start() gramatica.lstGrmaticales = [] lst = gramatica.lst_errores except: self.consola.append( "/\\/\\/\\/\\/\\ERROR DE LEXICO, SINTACTICO/\\/\\/\\/\\") self.consola.append("REVISAR REPORTE DE ERRORES") finally: if not self.analizador_cambiado: gramatica.graficarErrores() else: gramaticaD.graficarErrores() ts = TablaSimbolos() global in_console if self.debug_mode: in_console = Debuger(args=(ast if (ast != None) else ast, ts, lst, "", items[0], self.consola, self.GTS), daemon=True) else: in_console = Ejecutor(args=(ast if (ast != None) else ast, ts, lst, "", items[0], self.consola, self.GTS), daemon=True) if ast != None: try: print( "___________INICIA PROCESO DE ANALISIS SEMANTICO_______________" ) recolector = Recolectar(ast, ts, lst) print("******FIN CONSTRUCTOR**********") recolector.procesar() recolector.getErrores() print("******FIN RECOLECCION*******") print("********** FIN DE CONSTRUCTOR ********") in_console.start() except: self.consola.append( "/\\/\\/\\/\\/\\ERROR DE EJECUCION/\\/\\/\\/\\") self.consola.append("REVISAR REPORTE DE ERRORES") ts.graficarSimbolos()
import ply.lex as lex from ply.lex import TOKEN import sys import re from TablaSimbolos import TablaSimbolos from TablaSimbolos import Fun from gramatica import parser import gramatica lexema = "" tipo = None comentario = False tabla_simbolos = TablaSimbolos() estoy_en_fun = False #sirve para indicar si voy a leer una funcion flagFor = False flagFor2 = False contador = 0 contReturn = 0 contParentesis_1 = 0 flagIf = False metaFlagIf = False flagExpresion = False anotherFlag = False opEsp = False checkParentesis = False funPass = False listaExpresion = [] listaTokens = [] #Para pasarle al sintactico funcion = Fun() funcionAux = Fun() tipos = (
class GramaticaExtListener(GramaticaListener): #valoresEvaluados = collections.deque #tablaDeSimbolosActual = TablaSimbolos() def __init__(self): self.contextoActual = 0 self.pilaValores = collections.deque() self.tablaDeSimbolosActual = TablaSimbolos(None,0) # # # # # ESTRUCTURAS DE FLUJO Y CONTROL # # # # def exitIf_stmt(self, ctx): print("Nuevo if") valorTest = self.pilaValores.pop() print(valorTest.valor) print(len(ctx.elif_stmt()[0].stmt())) def exitAssig_stmt(self, ctx): nodo = self.pilaValores.pop() print(ctx.NAME().getText()) simbolo = Simbolo(ctx.NAME(),nodo.tipoValor,nodo.valor) self.tablaDeSimbolosActual.agregarSimbolo(ctx.NAME(), simbolo) print("Nuevo Simbolo: "+str(simbolo)) # # # # #SECCION DE COMPARACIONES Y TEST LOGICOS # # # # def exitOrTest(self, ctx): if len(ctx.and_test()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "BOOL" and valorI.tipoValor == "BOOL": nodo = Nodo() nodo.tipoValor = "BOOL" nodo.valor = valorD.valor or valorI.valor self.pilaValores.append(nodo) print("Nuevo ORT: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo logico') def exitAndTest(self, ctx): if len(ctx.not_test()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "BOOL" and valorI.tipoValor == "BOOL": nodo = Nodo() nodo.tipoValor = "BOOL" nodo.valor = valorD.valor and valorI.valor self.pilaValores.append(nodo) print("Nuevo ORT: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo logico') def exitNotExpr(self, ctx): nodo = self.pilaValores.pop() if nodo.tipoValor == "BOOL": nodo.valor = not nodo.valor self.pilaValores.append(nodo) print("Nuevo NOT: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo logico') def exitComparisonEval(self, ctx): valorI = self.pilaValores.pop() valorD = self.pilaValores.pop() nodo = Nodo() op = ctx.comp_op().getText() if op == "<": nodo.valor = valorI.valor < valorD.valor elif op == ">": nodo.valor = valorI.valor > valorD.valor elif op == "==": nodo.valor = valorI.valor == valorD.valor elif op == ">=": nodo.valor = valorI.valor >= valorD.valor elif op == "<=": nodo.valor = valorI.valor <= valorD.valor elif op == "<>": nodo.valor = valorI.valor <> valorD.valor elif op == "!=": nodo.valor = valorI.valor != valorD.valor nodo.tipoValor = "BOOL" self.pilaValores.append(nodo) print("Nueva compracion: "+str(nodo.valor)) # # # # #SECCION DE OPERADORES ARITMETICOS, SE DEBE TENER EN CUENTA EL TIPO DE OPERANDOS PARA ESTA PARTE # # # # def exitAndExpr(self, ctx): if len(ctx.or_expr()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "INTEGER" and valorI.tipoValor == "INTEGER": nodo = Nodo() nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor & valorI.valor self.pilaValores.append(nodo) print("Nuevo and: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo entero') def exitOrExpr(self, ctx): if len(ctx.xor_expr()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "INTEGER" and valorI.tipoValor == "INTEGER": nodo = Nodo() nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor | valorI.valor self.pilaValores.append(nodo) print("Nuevo or: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo entero') def exitXorExpr(self, ctx): if len(ctx.shift_expr()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "INTEGER" and valorI.tipoValor == "INTEGER": nodo = Nodo() nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor ^ valorI.valor self.pilaValores.append(nodo) print("Nuevo xor: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo entero') def exitShiftLeft(self, ctx): if len(ctx.arith_expr() ) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "INTEGER" and valorI.tipoValor == "INTEGER": nodo = Nodo() nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor << valorI.valor self.pilaValores.append(nodo) print("Nueva shift left: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo entero') def exitShiftRight(self, ctx): if len(ctx.arith_expr() ) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "INTEGER" and valorI.tipoValor == "INTEGER": nodo = Nodo() nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor >> valorI.valor self.pilaValores.append(nodo) print("Nueva shift right: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo entero') def exitArithPlus(self, ctx): if len(ctx.term()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() if valorD.tipoValor == "FLOAT" or valorI.tipoValor == "FLOAT" : nodo.tipoValor = "FLOAT" else: nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor + valorI.valor self.pilaValores.append(nodo) print("Nueva suma: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo numerico') def exitArithMinus(self, ctx): if len(ctx.term()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() if valorD.tipoValor == "FLOAT" or valorI.tipoValor == "FLOAT" : nodo.tipoValor = "FLOAT" else: nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor - valorI.valor self.pilaValores.append(nodo) print("Nueva resta: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo numerico') def exitTermProduct(self, ctx): if len(ctx.power()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() if valorD.tipoValor == "FLOAT" or valorI.tipoValor == "FLOAT" : nodo.tipoValor = "FLOAT" else: nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor * valorI.valor self.pilaValores.append(nodo) print("Nuevo producto: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo numerico') def exitTermDivision(self, ctx): if len(ctx.power()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() if valorD.tipoValor == "FLOAT" or valorI.tipoValor == "FLOAT" : nodo.tipoValor = "FLOAT" else: nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor / valorI.valor self.pilaValores.append(nodo) print("Nueva division: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo numerico') def exitTermModule(self, ctx): if len(ctx.power()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() if valorD.tipoValor == "FLOAT" or valorI.tipoValor == "FLOAT" : nodo.tipoValor = "FLOAT" else: nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor % valorI.valor self.pilaValores.append(nodo) print("Nuevo modulo: "+str(nodo.valor)) else: raise RuntimeError('Error en los operandos, deben ser de tipo numerico') def exitPowerEval(self, ctx): if len(ctx.atom_stmt()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() nodo.tipoValor = "FLOAT" nodo.valor = valorI.valor ** valorD.valor self.pilaValores.append(nodo) print("Nueva potencia: "+str(nodo.valor)) else: raise RuntimeError('Error en los operadores, deben ser de tipo entero') # # # # #LISTENER PARA LOS VALORES ATOMICOS # # # # def enterAtomName(self, ctx): nodo = Nodo() valor = self.evaluarSimbolo(ctx.NAME()) nodo.tipoValor = valor[0] nodo.valor = valor[1] self.pilaValores.append(nodo) def enterAtomString(self, ctx): nodo = Nodo() nodo.valor = ctx.string() nodo.tipoValor = "STRING" self.pilaValores.append(nodo) def enterAtomNone(self, ctx): nodo = Nodo() nodo.valor = None nodo.tipoValor = "NONE" self.pilaValores.append(nodo) def enterAtomTrue(self, ctx): nodo = Nodo() nodo.valor = True nodo.tipoValor = "BOOL" self.pilaValores.append(nodo) def enterAtomFalse(self, ctx): nodo = Nodo() nodo.valor = False nodo.tipoValor = "BOOL" self.pilaValores.append(nodo) # # # # #LISTENER PARA LOS VALORES NUMERICOS # # # # def enterNumberInteger(self, ctx): valor = int(ctx.integer().getText()) nodo = Nodo() nodo.valor = valor nodo.tipoValor = "INTEGER" self.pilaValores.append(nodo) def enterNumberFloat(self, ctx): valor = float(ctx.FLOAT_NUMBER().getText()) nodo = Nodo() nodo.valor = valor nodo.tipoValor = "FLOAT" self.pilaValores.append(nodo) # # # # # UTILIDADES VARIAS # # # # def evaluarSimbolo(self,nombre): valor = self.tablaDeSimbolosActual.resolver(nombre) if valor == None: raise RuntimeError('Error Simbolo no encontrado: '+str(nombre)) return (valor.tipo,valor.valor) def numerico(self,nodo): return nodo.tipoValor == "INTEGER" or nodo.tipoValor == "FLOAT" def obtenerRetorno(self): return self.pilaValores.pop()
def __init__(self): self.contextoActual = 0 self.pilaValores = collections.deque() self.tablaDeSimbolosActual = TablaSimbolos(None,0)
def __init__(self, an): #super(GramaticaExtListener,self) self.tablaDeSimbolosActual = TablaSimbolos(None, 0) self.pilaValores = collections.deque() self.an = an
class GramaticaExtVisitor(GramaticaVisitor): def __init__(self, an): #super(GramaticaExtListener,self) self.tablaDeSimbolosActual = TablaSimbolos(None, 0) self.pilaValores = collections.deque() self.an = an # # # # # SECCION DE FUNCIONES # # # # def visitPrint_fun(self, ctx): valor = super(GramaticaExtVisitor, self).visit(ctx.test()) ret = "" if valor.tipo == "ITERATOR" and valor.subtipo == "LIST": ret = "[" for x in valor.valor: ret += str(x.valor) + ", " ret = ret[0:len(ret) - 2] ret += "]" elif valor.tipo == "ITERATOR" and valor.subtipo == "TUPLE": ret = "(" + str(valor.valor[0].valor) + ", " + str( valor.valor[1].valor) + ")" elif valor.tipo == "ITERATOR" and valor.subtipo == "MAP": ret = "{" for ky in valor.valor: ret += str(ky) + ":" + str(valor.valor[ky].valor) + ", " ret += "}" else: ret = str(valor.valor) self.an.agregarRegistro(str(ret)) def visitFuncdef(self, ctx): simbolo = Simbolo(ctx.NAME(), "FUNCION", ctx.funcBody()) simbolo.argumentos = [] if ctx.args() != None: simbolo.argumentos.append(ctx.args().NAME()) if len(ctx.args().sub_args()) > 0: for argtmp in ctx.args().sub_args(): simbolo.argumentos.append(argtmp.NAME()) simbolo.parametrosLambda = ctx.lambdaParamet() self.tablaDeSimbolosActual.agregarSimbolo(ctx.NAME(), simbolo) def visitFuncBodyNormal(self, ctx): return self.evaluarInstrucciones(ctx.stmt()) def visitFuncBodyMatch(self, ctx): self.pilaValores.append(str(ctx.NAME())) for mst in ctx.match_stmt(): r = super(GramaticaExtVisitor, self).visit(mst) if r != None: return r self.pilaValores.pop() def visitMatch_stmt(self, ctx): nombre = self.pilaValores.pop() self.pilaValores.append(nombre) valor = super(GramaticaExtVisitor, self).visit(ctx.test()) simbolo = self.tablaDeSimbolosActual.resolver(nombre) if simbolo.tipo == valor.tipo and simbolo.valor == valor.valor: ret = self.evaluarInstrucciones(ctx.stmt()) if ret != None: return ret return None def visitFunc_call(self, ctx): return self.evaluarFuncion(ctx) # # # # # SECCION DE BLOQUES DE CONTROL Y FLUJO # # # # def visitIf_stmt(self, ctx): cond = super(GramaticaExtVisitor, self).visit(ctx.test()) if self.evaluarIf(cond, ctx.stmt()): return None if len(ctx.elif_stmt()) > 0: for nodo_elif in ctx.elif_stmt(): cond = super(GramaticaExtVisitor, self).visit(nodo_elif.test()) if self.evaluarIf(cond, nodo_elif.stmt()): return None if len(ctx.else_stmt()) > 0: nodo = Nodo() nodo.tipo = "BOOL" nodo.valor = True self.evaluarIf(nodo, ctx.else_stmt().stmt()) return None def visitWhile_stmt(self, ctx): valor = super(GramaticaExtVisitor, self).visit(ctx.test()) if valor.tipo != "BOOL": ln = -1 self.raiseError(ln, 'La expresion del while debe ser de tipo logica', "logic-expected") while valor.valor: self.evaluarInstrucciones(ctx.stmt()) valor = super(GramaticaExtVisitor, self).visit(ctx.test()) return None def visitBreak_stmt(self, ctx): nodo = Nodo() nodo.tipo = "BREAK" return nodo def visitContinue_stmt(self, ctx): nodo = Nodo() nodo.tipo = "CONTINUE" return nodo def visitReturn_stmt(self, ctx): return super(GramaticaExtVisitor, self).visit(ctx.test()) def visitAssig_stmtVar(self, ctx): valor = super(GramaticaExtVisitor, self).visit(ctx.test()) simbolo = Simbolo(ctx.NAME(), valor.tipo, valor.valor) simbolo.subtipo = valor.subtipo self.tablaDeSimbolosActual.agregarSimbolo(ctx.NAME(), simbolo) return None def visitAssig_stmtIterable(self, ctx): simbolo = self.tablaDeSimbolosActual.resolver(ctx.NAME()) if simbolo == None: ln = -1 self.raiseError(ln, 'No se ha encontrado el simbolo', ctx.NAME()) elif simbolo.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El simbolo es no iterable', "iterable-expected") indice = super(GramaticaExtVisitor, self).visit(ctx.test(0)) valor = super(GramaticaExtVisitor, self).visit(ctx.test(1)) simbolo.valor[indice] = valor return None def visitFor_stmt(self, ctx): nm = ctx.NAME() iterab = super(GramaticaExtVisitor, self).visit(ctx.iterable()) if iterab == None: ln = -1 self.raiseError(ln, 'No es posible obtener el iterable', "iterable-gen") elif iterab.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El simbolo no es iterable', "iterable-expected") elif iterab.subtipo == "TUPLE": ln = -1 self.raiseError( ln, 'No es posible realizar un recorrido sobre una tupla', "iterable-tuple") self.tablaDeSimbolosActual = TablaSimbolos( self.tablaDeSimbolosActual, self.tablaDeSimbolosActual.contexto) self.tablaDeSimbolosActual.agregarSimbolo(nm, Simbolo(nm, None, None)) for tmp in iterab.valor: self.tablaDeSimbolosActual.agregarSimbolo( nm, Simbolo(nm, tmp.tipo, tmp.valor)) self.evaluarInstrucciones(ctx.stmt()) self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla() # # # # # SECCION DEFINICION ITERABLES # # # # def visitIterable_list(self, ctx): nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "LIST" nodo.valor = [] if ctx.list_element() != None: valor = super(GramaticaExtVisitor, self).visit(ctx.list_element().test()) nodo.valor.append(valor) if ctx.list_element() != None and ctx.list_element().sublist_element( ) != None: for el in ctx.list_element().sublist_element(): valor = super(GramaticaExtVisitor, self).visit(el.test()) nodo.valor.append(valor) return nodo def visitIterable_map(self, ctx): nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "MAP" nodo.valor = {} if ctx.map_element() != None: indice = super(GramaticaExtVisitor, self).visit(ctx.map_element().test(0)) valor = super(GramaticaExtVisitor, self).visit(ctx.map_element().test(1)) nodo.valor[indice.valor] = valor if ctx.map_element() != None and ctx.map_element().submap_element( ) != None: for el in ctx.map_element().submap_element(): indice = super(GramaticaExtVisitor, self).visit(el.test(0)) valor = super(GramaticaExtVisitor, self).visit(el.test(1)) nodo.valor[indice.valor] = valor return nodo def visitIterable_tuple(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.test(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.test(1)) nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "TUPLE" nodo.valor = (valorI, valorD) return nodo def visitIterable_generate(self, ctx): valor = super(GramaticaExtVisitor, self).visit(ctx.test()) if valor.tipo == "INTEGER": nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "LIST" nodo.valor = [] for x in xrange(valor.valor): tmp = Nodo() tmp.tipo = "INTEGER" tmp.valor = x nodo.valor.append(tmp) return nodo elif valor.tipo == "STRING": nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "LIST" nodo.valor = [] for x in valor.valor: tmp = Nodo() tmp.valor = x tmp.tipo = "STRING" nodo.valor.append(tmp) return nodo else: ln = -1 self.raiseError( ln, 'Error en el generador, este debe ser de tipo cadena o entero', "non-iterable") def visitIterable_filter(self, ctx): iterab = super(GramaticaExtVisitor, self).visit(ctx.iterable()) if iterab == None: ln = -1 self.raiseError(ln, 'Error al evaluar el iterador', "iterator-eval") if iterab.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El objeto especificado no es de tipo iterable', "iterable-expected") if iterab.subtipo == "TUPLE": ln = -1 self.raiseError( ln, 'No es posible realizar un recorrido sobre una tupla', "iterable-tuple") filtrada = None if iterab.subtipo == "LIST": filtrada = [] else: filtrada = {} self.tablaDeSimbolosActual = TablaSimbolos( self.tablaDeSimbolosActual, self.tablaDeSimbolosActual.contexto) for tmp in iterab.valor: ac = None ty = None if iterab.subtipo == "LIST": ac = tmp.valor ty = tmp.tipo else: ac = iterab.valor[tmp].valor ty = iterab.valor[tmp].tipo simbolo = Simbolo(ctx.lambda_test().NAME(), ty, ac) self.tablaDeSimbolosActual.agregarSimbolo(simbolo.nombre, simbolo) res = super(GramaticaExtVisitor, self).visit(ctx.lambda_test().test()) if res.tipo != "BOOL": ln = -1 self.raiseError( ln, 'No es posible filtrar bajo la funcion especificada', "lambda-filter-error") if res.valor == True and iterab.subtipo == "LIST": filtrada.append(tmp) elif res.valor == True and iterab.subtipo == "MAP": filtrada[tmp] = iterab.valor[tmp] self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla() nodo = Nodo() nodo.subtipo = iterab.subtipo nodo.tipo = "ITERATOR" nodo.valor = filtrada return nodo def visitIterable_partition(self, ctx): pass def visitIterable_name(self, ctx): valor = self.tablaDeSimbolosActual.resolver(ctx.NAME()) if valor == None: ln = -1 self.raiseError(ln, 'El simbolo no se ha encontrado', ctx.NAME()) if valor.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El nombre no es de tipo iterador', ctx.NAME()) nodo = Nodo() nodo.tipo = valor.tipo nodo.subtipo = valor.subtipo nodo.valor = valor.valor return nodo def unirIterables(self, iterab1, iterab2): if iterab1 == None or iterab2 == None: ln = -1 self.raiseError(ln, "No se han proporcionado elementos para operar", "operators-expected") if iterab1.tipo != "ITERATOR" or iterab2.tipo != "ITERATOR": ln = -1 self.raiseError(ln, "Se han proporcionado tipos no iterables", "iterable-expected") if iterab1.subtipo == "MAP" or iterab2.subtipo == "MAP": print(iterab1.subtipo) print(iterab2.subtipo) if iterab1.subtipo == "MAP" and iterab2.subtipo == "MAP": nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "MAP" nodo.valor = {} for k in iterab2.valor: nodo.valor[k] = iterab2.valor[k] for k in iterab1.valor: nodo.valor[k] = iterab1.valor[k] return nodo elif iterab1.subtipo == "TUPLE" and iterab2.subtipo == "MAP": nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "MAP" nodo.valor = iterab2.valor nodo.valor[iterab1.valor[0].valor] = iterab1.valor[1] return nodo else: ln = -1 self.raiseError( ln, "No es posible concatenar un mapa con algun otro iterable", "tuple,map-expected") nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "LIST" nodo.valor = [] for k in iterab1.valor: nodo.valor.append(k) for k in iterab2.valor: nodo.valor.append(k) return nodo def visitIterable_addition(self, ctx): vl = super(GramaticaExtVisitor, self).visit(ctx.iterable(0)) iterab = super(GramaticaExtVisitor, self).visit(ctx.iterable(1)) if iterab == None or vl == None: ln = -1 self.raiseError(ln, "No se han proporcionado elementos para operar", "operators-expected") if iterab.tipo != "ITERATOR": ln = -1 self.raiseError( ln, "No es posible realizar esta operacion sobre un elemento no iterable", "iterable-expected") if vl.tipo == "ITERATOR": return self.unirIterables(vl, iterab) if iterab.tipo == "MAP": ln = -1 self.raiseError(ln, "No es posible agregar ese elemento en un mapa", "tuple,map-expected") nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "LIST" nodo.valor = [vl] + iterab.valor return nodo # # # # #SECCION DE COMPARACIONES Y TEST LOGICOS # # # # def visitTestAnd(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.test(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.test(1)) nodo = Nodo() if valorI.tipo == "BOOL" and valorD.tipo == "BOOL": nodo.tipo = "BOOL" nodo.valor = valorI.valor and valorD.tipo else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion and-test") return nodo def visitTestOr(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.test(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.test(1)) nodo = Nodo() if valorI.tipo == "BOOL" and valorD.tipo == "BOOL": nodo.tipo = "BOOL" nodo.valor = valorI.valor or valorD.tipo else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion or-test") return nodo def visitTestNot(self, ctx): valor = super(GramaticaExtVisitor, self).visit(ctx.test(0)) nodo = Nodo() if valor.tipo == "BOOL": nodo.tipo = "BOOL" nodo.valor = not valor.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion not-test") return nodo def visitTestExprComp(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() nodo.tipo = "BOOL" op = ctx.comp_op().getText() if valorI.tipo == "ITERATOR" or valorD.tipo == "ITERATOR": ln = -1 self.raiseError( ln, "No es posible realizar este tipo de operacion con elementos iterables", "primitive-expected") if op == "<": nodo.valor = valorI.valor < valorD.valor elif op == ">": nodo.valor = valorI.valor > valorD.valor elif op == "==": nodo.valor = valorI.valor == valorD.valor elif op == ">=": nodo.valor = valorI.valor >= valorD.valor elif op == "<=": nodo.valor = valorI.valor <= valorD.valor elif op == "<>": nodo.valor = valorI.valor <> valorD.valor elif op == "!=": nodo.valor = valorI.valor != valorD.valor return nodo def visitTest_iterable_in(self, ctx): vl = super(GramaticaExtVisitor, self).visit(ctx.test()) iterab = super(GramaticaExtVisitor, self).visit(ctx.iterable()) if iterab == None or vl == None: ln = -1 self.raiseError(ln, "No se han proporcionado elementos para operar", "operators-expected") if iterab.tipo != "ITERATOR": ln = -1 self.raiseError( ln, "No es posible realizar esta operacion sobre un elemento no iterable", "iterable-expected") nodo = Nodo() nodo.tipo = "BOOL" nodo.valor = False for t in iterab: if t.tipo == vl.tipo and t.valor == vl.valor: nodo.valor = True return nodo return nodo # # # # #SECCION DE OPERADORES ARITMETICOS, SE DEBE TENER EN CUENTA EL TIPO DE OPERANDOS PARA ESTA PARTE # # # # def visitExprPower(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if self.numerico(valorI) and self.numerico(valorD): if valorI.tipo == "FLOAT" or valorD.tipo == "FLOAT": nodo.tipo = "FLOAT" else: nodo.tipo = "INTEGER" nodo.valor = valorI.valor**valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion potencia") return nodo def visitExprMultiply(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if self.numerico(valorI) and self.numerico(valorD): if valorI.tipo == "FLOAT" or valorD.tipo == "FLOAT": nodo.tipo = "FLOAT" else: nodo.tipo = "INTEGER" nodo.valor = valorI.valor * valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion multiplicacion") return nodo def visitExprDivision(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if self.numerico(valorI) and self.numerico(valorD): if valorI.tipo == "FLOAT" or valorD.tipo == "FLOAT": nodo.tipo = "FLOAT" else: nodo.tipo = "INTEGER" nodo.valor = valorI.valor / valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion division") return nodo def visitExprModule(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor % valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion modulo") return nodo def visitExprPlus(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if self.numerico(valorI) and self.numerico(valorD): if valorI.tipo == "FLOAT" or valorD.tipo == "FLOAT": nodo.tipo = "FLOAT" else: nodo.tipo = "INTEGER" nodo.valor = valorI.valor + valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion suma") return nodo def visitExprMinus(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if self.numerico(valorI) and self.numerico(valorD): if valorI.tipo == "FLOAT" or valorD.tipo == "FLOAT": nodo.tipo = "FLOAT" else: nodo.tipo = "INTEGER" nodo.valor = valorI.valor - valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion resta") return nodo def visitExprShiftLeft(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor << valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion shift-left") return nodo def visitExprShiftRight(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor >> valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion shift-right") return nodo def visitExprAnd(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor & valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion bit-and") return nodo def visitExprOr(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor | valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion bit-or") return nodo def visitExprXor(self, ctx): valorI = super(GramaticaExtVisitor, self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor, self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor ^ valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion bit-xor") return nodo # # # # #LISTENER PARA LOS VALORES ATOMICOS # # # # def visitAtomName(self, ctx): nodo = Nodo() valor = self.evaluarSimbolo(ctx.NAME()) nodo.tipo = valor.tipo nodo.valor = valor.valor nodo.subtipo = valor.subtipo #self.pilaValores.append(nodo) return nodo def visitAtomString(self, ctx): nodo = Nodo() nodo.valor = str(ctx.STRING()) nodo.valor = nodo.valor[1:len(nodo.valor) - 1] nodo.tipo = "STRING" #self.pilaValores.append(nodo) return nodo def visitAtomNone(self, ctx): nodo = Nodo() nodo.valor = None nodo.tipo = "NONE" #self.pilaValores.append(nodo) return nodo def visitAtomTrue(self, ctx): nodo = Nodo() nodo.valor = True nodo.tipo = "BOOL" #self.pilaValores.append(nodo) return nodo def visitAtomFalse(self, ctx): nodo = Nodo() nodo.valor = False nodo.tipo = "BOOL" #self.pilaValores.append(nodo) return nodo def visitAtomFuncCall(self, ctx): return self.evaluarFuncion(ctx) def visitAtomIterableAccess(self, ctx): simbolo = self.tablaDeSimbolosActual.resolver(ctx.NAME()) if simbolo == None: ln = -1 self.raiseError(ln, 'Simbolo no encontrado', ctx.NAME()) elif simbolo.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El objeto no es interable', ctx.NAME()) indice = super(GramaticaExtVisitor, self).visit(ctx.test()) return simbolo.valor[indice.valor] def visitAtomIterableDef(self, ctx): return super(GramaticaExtVisitor, self).visit(ctx.iterable()) # # # # #LISTENER PARA LOS VALORES NUMERICOS # # # # def visitNumberInteger(self, ctx): valor = int(ctx.integer().getText()) nodo = Nodo() nodo.valor = valor nodo.tipo = "INTEGER" #self.pilaValores.append(nodo) return nodo def visitNumberFloat(self, ctx): valor = float(ctx.FLOAT_NUMBER().getText()) nodo = Nodo() nodo.valor = valor nodo.tipo = "FLOAT" #self.pilaValores.append(nodo) return nodo # # # # # UTILIDADES VARIAS # # # # def evaluarSimbolo(self, nombre): valor = self.tablaDeSimbolosActual.resolver(nombre) if valor == None: ln = -1 self.raiseError(ln, 'Error simbolo no encontrado', nombre) return valor def numerico(self, nodo): return nodo.tipo == "INTEGER" or nodo.tipo == "FLOAT" def evaluarIf(self, nodo, instrucciones): if nodo.tipo == "BOOL" and nodo.valor == True: self.evalurInstrucciones(instrucciones) return True return False def evaluarInstrucciones(self, instrucciones): for inst in instrucciones: r = super(GramaticaExtVisitor, self).visit(inst) if inst.flow_stmt() != None and inst.flow_stmt().return_stmt( ) != None: return r return None def evaluarArgumento(self, arg): valor = super(GramaticaExtVisitor, self).visit(arg) return (valor.tipo, valor.valor) def evaluarFuncion(self, ctx): simbolo = self.tablaDeSimbolosActual.resolver(ctx.NAME()) if simbolo == None: ln = -1 self.raiseError(ln, 'Error en el simbolo', ctx.NAME()) if simbolo.tipo != "FUNCION": ln = -1 self.raiseError( ln, 'Error, el simbolo no puede ser evaluado como una funcion', ctx.NAME()) parametros = [] if ctx.parameters() != None: parametros.append(ctx.parameters().test()) if len(ctx.parameters().sub_parameters()) > 0: for param in ctx.parameters().sub_parameters(): parametros.append(param.test()) if len(parametros) != len(simbolo.argumentos): ln = -1 self.raiseError(ln, "Error en la cantidad de parametros", ctx.NAME()) nuevaTablaSimbolos = TablaSimbolos( self.tablaDeSimbolosActual, self.tablaDeSimbolosActual.contexto + 1) for i in xrange(0, len(parametros)): argument = self.evaluarArgumento(parametros[i]) simboloNuevo = Simbolo(simbolo.argumentos[i], argument[0], argument[1]) nuevaTablaSimbolos.agregarSimbolo(simbolo.argumentos[i], simboloNuevo) self.tablaDeSimbolosActual = nuevaTablaSimbolos r = super(GramaticaExtVisitor, self).visit(simbolo.valor) self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla() if r != None: return r return None def raiseError(self, ln, msg, smb): ret = "Airi dice: Error en la linea " + str( ln) + " se ha producido el siguiente error: " + str( msg) + " con el simbolo: " + str( smb) + ", por favor revise la entrada" raise RuntimeError(ret)
class GramaticaExtListener(GramaticaListener): # valoresEvaluados = collections.deque # tablaDeSimbolosActual = TablaSimbolos() def __init__(self): self.contextoActual = 0 self.pilaValores = collections.deque() self.tablaDeSimbolosActual = TablaSimbolos(None, 0) # # # # # ESTRUCTURAS DE FLUJO Y CONTROL # # # # def exitIf_stmt(self, ctx): print("Nuevo if") valorTest = self.pilaValores.pop() print(valorTest.valor) print(len(ctx.elif_stmt()[0].stmt())) def exitAssig_stmt(self, ctx): nodo = self.pilaValores.pop() print(ctx.NAME().getText()) simbolo = Simbolo(ctx.NAME(), nodo.tipoValor, nodo.valor) self.tablaDeSimbolosActual.agregarSimbolo(ctx.NAME(), simbolo) print("Nuevo Simbolo: " + str(simbolo)) # # # # # SECCION DE COMPARACIONES Y TEST LOGICOS # # # # def exitOrTest(self, ctx): if len(ctx.and_test()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "BOOL" and valorI.tipoValor == "BOOL": nodo = Nodo() nodo.tipoValor = "BOOL" nodo.valor = valorD.valor or valorI.valor self.pilaValores.append(nodo) print("Nuevo ORT: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo logico") def exitAndTest(self, ctx): if len(ctx.not_test()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "BOOL" and valorI.tipoValor == "BOOL": nodo = Nodo() nodo.tipoValor = "BOOL" nodo.valor = valorD.valor and valorI.valor self.pilaValores.append(nodo) print("Nuevo ORT: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo logico") def exitNotExpr(self, ctx): nodo = self.pilaValores.pop() if nodo.tipoValor == "BOOL": nodo.valor = not nodo.valor self.pilaValores.append(nodo) print("Nuevo NOT: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo logico") def exitComparisonEval(self, ctx): valorI = self.pilaValores.pop() valorD = self.pilaValores.pop() nodo = Nodo() op = ctx.comp_op().getText() if op == "<": nodo.valor = valorI.valor < valorD.valor elif op == ">": nodo.valor = valorI.valor > valorD.valor elif op == "==": nodo.valor = valorI.valor == valorD.valor elif op == ">=": nodo.valor = valorI.valor >= valorD.valor elif op == "<=": nodo.valor = valorI.valor <= valorD.valor elif op == "<>": nodo.valor = valorI.valor <> valorD.valor elif op == "!=": nodo.valor = valorI.valor != valorD.valor nodo.tipoValor = "BOOL" self.pilaValores.append(nodo) print("Nueva compracion: " + str(nodo.valor)) # # # # # SECCION DE OPERADORES ARITMETICOS, SE DEBE TENER EN CUENTA EL TIPO DE OPERANDOS PARA ESTA PARTE # # # # def exitAndExpr(self, ctx): if len(ctx.or_expr()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "INTEGER" and valorI.tipoValor == "INTEGER": nodo = Nodo() nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor & valorI.valor self.pilaValores.append(nodo) print("Nuevo and: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo entero") def exitOrExpr(self, ctx): if len(ctx.xor_expr()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "INTEGER" and valorI.tipoValor == "INTEGER": nodo = Nodo() nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor | valorI.valor self.pilaValores.append(nodo) print("Nuevo or: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo entero") def exitXorExpr(self, ctx): if len(ctx.shift_expr()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "INTEGER" and valorI.tipoValor == "INTEGER": nodo = Nodo() nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor ^ valorI.valor self.pilaValores.append(nodo) print("Nuevo xor: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo entero") def exitShiftLeft(self, ctx): if len(ctx.arith_expr()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "INTEGER" and valorI.tipoValor == "INTEGER": nodo = Nodo() nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor << valorI.valor self.pilaValores.append(nodo) print("Nueva shift left: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo entero") def exitShiftRight(self, ctx): if len(ctx.arith_expr()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if valorD.tipoValor == "INTEGER" and valorI.tipoValor == "INTEGER": nodo = Nodo() nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor >> valorI.valor self.pilaValores.append(nodo) print("Nueva shift right: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo entero") def exitArithPlus(self, ctx): if len(ctx.term()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() if valorD.tipoValor == "FLOAT" or valorI.tipoValor == "FLOAT": nodo.tipoValor = "FLOAT" else: nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor + valorI.valor self.pilaValores.append(nodo) print("Nueva suma: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo numerico") def exitArithMinus(self, ctx): if len(ctx.term()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() if valorD.tipoValor == "FLOAT" or valorI.tipoValor == "FLOAT": nodo.tipoValor = "FLOAT" else: nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor - valorI.valor self.pilaValores.append(nodo) print("Nueva resta: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo numerico") def exitTermProduct(self, ctx): if len(ctx.power()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() if valorD.tipoValor == "FLOAT" or valorI.tipoValor == "FLOAT": nodo.tipoValor = "FLOAT" else: nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor * valorI.valor self.pilaValores.append(nodo) print("Nuevo producto: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo numerico") def exitTermDivision(self, ctx): if len(ctx.power()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() if valorD.tipoValor == "FLOAT" or valorI.tipoValor == "FLOAT": nodo.tipoValor = "FLOAT" else: nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor / valorI.valor self.pilaValores.append(nodo) print("Nueva division: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo numerico") def exitTermModule(self, ctx): if len(ctx.power()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() if valorD.tipoValor == "FLOAT" or valorI.tipoValor == "FLOAT": nodo.tipoValor = "FLOAT" else: nodo.tipoValor = "INTEGER" nodo.valor = valorD.valor % valorI.valor self.pilaValores.append(nodo) print("Nuevo modulo: " + str(nodo.valor)) else: raise RuntimeError("Error en los operandos, deben ser de tipo numerico") def exitPowerEval(self, ctx): if len(ctx.atom_stmt()) == 2: valorD = self.pilaValores.pop() valorI = self.pilaValores.pop() if self.numerico(valorD) and self.numerico(valorI): nodo = Nodo() nodo.tipoValor = "FLOAT" nodo.valor = valorI.valor ** valorD.valor self.pilaValores.append(nodo) print("Nueva potencia: " + str(nodo.valor)) else: raise RuntimeError("Error en los operadores, deben ser de tipo entero") # # # # # LISTENER PARA LOS VALORES ATOMICOS # # # # def enterAtomName(self, ctx): nodo = Nodo() valor = self.evaluarSimbolo(ctx.NAME()) nodo.tipoValor = valor[0] nodo.valor = valor[1] self.pilaValores.append(nodo) def enterAtomString(self, ctx): nodo = Nodo() nodo.valor = ctx.string() nodo.tipoValor = "STRING" self.pilaValores.append(nodo) def enterAtomNone(self, ctx): nodo = Nodo() nodo.valor = None nodo.tipoValor = "NONE" self.pilaValores.append(nodo) def enterAtomTrue(self, ctx): nodo = Nodo() nodo.valor = True nodo.tipoValor = "BOOL" self.pilaValores.append(nodo) def enterAtomFalse(self, ctx): nodo = Nodo() nodo.valor = False nodo.tipoValor = "BOOL" self.pilaValores.append(nodo) # # # # # LISTENER PARA LOS VALORES NUMERICOS # # # # def enterNumberInteger(self, ctx): valor = int(ctx.integer().getText()) nodo = Nodo() nodo.valor = valor nodo.tipoValor = "INTEGER" self.pilaValores.append(nodo) def enterNumberFloat(self, ctx): valor = float(ctx.FLOAT_NUMBER().getText()) nodo = Nodo() nodo.valor = valor nodo.tipoValor = "FLOAT" self.pilaValores.append(nodo) # # # # # UTILIDADES VARIAS # # # # def evaluarSimbolo(self, nombre): valor = self.tablaDeSimbolosActual.resolver(nombre) if valor == None: raise RuntimeError("Error Simbolo no encontrado: " + str(nombre)) return (valor.tipo, valor.valor) def numerico(self, nodo): return nodo.tipoValor == "INTEGER" or nodo.tipoValor == "FLOAT" def obtenerRetorno(self): return self.pilaValores.pop()
def __init__(self): self.contextoActual = 0 self.pilaValores = collections.deque() self.tablaDeSimbolosActual = TablaSimbolos(None, 0)
def __init__(self,an): #super(GramaticaExtListener,self) self.tablaDeSimbolosActual = TablaSimbolos(None,0) self.pilaValores = collections.deque() self.an = an
class GramaticaExtVisitor(GramaticaVisitor): _NONE = Simbolo("NONE","NONE","NONE") _BREAK = Simbolo("BREAK","BREAK","BREAK") _CONTINUE = Simbolo("CONTINUE","CONTINUE","CONTINUE") def __init__(self,an): #super(GramaticaExtListener,self) self.tablaDeSimbolosActual = TablaSimbolos(None,0) self.pilaValores = collections.deque() self.an = an # # # # # SECCION DE FUNCIONES # # # # def visitPrint_fun(self,ctx): valor = super(GramaticaExtVisitor,self).visit(ctx.test()) ret = ""; if valor == self._NONE or valor == None: ret = "None" elif valor.tipo == "ITERATOR" and valor.subtipo == "LIST": ret = "["; for x in valor.valor: ret += str(x.valor)+", " ret = ret[0:len(ret)-2] ret += "]" elif valor.tipo == "ITERATOR" and valor.subtipo == "TUPLE": ret = "("+str(valor.valor[0].valor)+", "+str(valor.valor[1].valor)+")" elif valor.tipo == "ITERATOR" and valor.subtipo == "MAP": ret = "{" for ky in valor.valor: ret += str(ky)+":"+str(valor.valor[ky].valor)+ ", " ret += "}" else: ret = str(valor.valor) self.an.agregarRegistro(str(ret)) return self._NONE def visitFuncdef(self, ctx): simbolo = Simbolo(ctx.NAME(),"FUNCION",ctx.funcBody()) simbolo.argumentos = [] if ctx.args() != None: simbolo.argumentos.append(ctx.args().NAME()) if len(ctx.args().sub_args()) > 0: for argtmp in ctx.args().sub_args(): simbolo.argumentos.append( argtmp.NAME() ) simbolo.parametrosLambda = ctx.lambdaParamet() self.tablaDeSimbolosActual.agregarSimbolo(ctx.NAME(), simbolo) def visitFuncBodyNormal(self, ctx): return self.evaluarInstrucciones(ctx.stmt()) def visitFuncBodyMatch(self, ctx): self.pilaValores.append(str(ctx.NAME())) for mst in ctx.match_stmt(): r = super(GramaticaExtVisitor,self).visit(mst) if r != self._NONE: return r self.pilaValores.pop() return self._NONE def visitMatch_stmt(self, ctx): nombre = self.pilaValores.pop() self.pilaValores.append(nombre) valor = super(GramaticaExtVisitor,self).visit(ctx.test()) simbolo = self.tablaDeSimbolosActual.resolver(nombre) #print("llamada") print(str(self.tablaDeSimbolosActual)) if simbolo.tipo == valor.tipo and simbolo.valor == valor.valor: ret = self.evaluarInstrucciones(ctx.stmt()) #print(ret) if ret != self._NONE: return ret return self._NONE def visitFunc_call(self, ctx): ret = self.evaluarFuncion(ctx) print(str(ret)) return ret # # # # # SECCION DE BLOQUES DE CONTROL Y FLUJO # # # # def visitIf_stmt(self, ctx): cond = super(GramaticaExtVisitor,self).visit(ctx.test()) if cond.tipo == "BOOL" and cond.valor == True: print("OK, entradda en if ") ret = self.evaluarInstrucciones(ctx.stmt()) print(str(ret)) return ret if ctx.elif_stmt() != None and len(ctx.elif_stmt()) > 0: for nodo_elif in ctx.elif_stmt(): cond = super(GramaticaExtVisitor,self).visit(nodo_elif.test()) if cond.tipo == "BOOL" and cond.valor == True: return self.evaluarInstrucciones(nodo_elif.stmt()) if ctx.else_stmt() != None: return self.evaluarInstrucciones(ctx.else_stmt().stmt()) return self._NONE def visitBreak_stmt(self, ctx): return self._BREAK def visitContinue_stmt(self, ctx): return self._CONTINUE def visitReturn_stmt(self, ctx): return super(GramaticaExtVisitor,self).visit(ctx.test()) def visitAssig_stmtVar(self, ctx): valor = super(GramaticaExtVisitor,self).visit(ctx.test()) simbolo = Simbolo(ctx.NAME(),valor.tipo,valor.valor) simbolo.subtipo = valor.subtipo self.tablaDeSimbolosActual.agregarSimbolo(ctx.NAME(), simbolo) return self._NONE def visitWhile_stmt(self, ctx): valor = super(GramaticaExtVisitor,self).visit(ctx.test()) if valor.tipo != "BOOL": ln = -1 self.raiseError(ln, 'La expresion del while debe ser de tipo logica', "logic-expected") while valor.valor : ret = self.evaluarInstrucciones(ctx.stmt()) if ret == self._BREAK: break elif ret != self._NONE and ret != self._CONTINUE: print("entro en return "+str(ret)) return ret valor = super(GramaticaExtVisitor,self).visit(ctx.test()) print("valor test: "+str(valor)) return self._NONE def visitAssig_stmtIterable(self, ctx): simbolo = self.tablaDeSimbolosActual.resolver(ctx.NAME()) if simbolo == None: ln = -1 self.raiseError(ln, 'No se ha encontrado el simbolo', ctx.NAME()) elif simbolo.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El simbolo es no iterable', "iterable-expected") indice = super(GramaticaExtVisitor,self).visit(ctx.test(0)) valor = super(GramaticaExtVisitor,self).visit(ctx.test(1)) simbolo.valor[indice] = valor return self._NONE def visitFor_stmt(self, ctx): nm = ctx.NAME() iterab = super(GramaticaExtVisitor,self).visit(ctx.iterable()) if iterab == None: ln = -1 self.raiseError(ln, 'No es posible obtener el iterable', "iterable-gen") elif iterab.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El simbolo no es iterable', "iterable-expected") elif iterab.subtipo == "TUPLE": ln = -1 self.raiseError(ln, 'No es posible realizar un recorrido sobre una tupla', "iterable-tuple") self.tablaDeSimbolosActual = TablaSimbolos(self.tablaDeSimbolosActual,self.tablaDeSimbolosActual.contexto) self.tablaDeSimbolosActual.agregarSimbolo(nm,Simbolo(nm,None,None)) for tmp in iterab.valor: self.tablaDeSimbolosActual.agregarSimbolo(nm,Simbolo(nm,tmp.tipo,tmp.valor)) self.evaluarInstrucciones(ctx.stmt()) self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla() # # # # # SECCION DEFINICION ITERABLES # # # # def visitIterable_list(self, ctx): nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "LIST" nodo.valor = [] if ctx.list_element() != None: valor = super(GramaticaExtVisitor,self).visit(ctx.list_element().test()) nodo.valor.append(valor) if ctx.list_element() != None and ctx.list_element().sublist_element() != None: for el in ctx.list_element().sublist_element(): valor = super(GramaticaExtVisitor,self).visit(el.test()) nodo.valor.append(valor) return nodo def visitIterable_map(self, ctx): nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "MAP" nodo.valor = {} if ctx.map_element() != None: indice = super(GramaticaExtVisitor,self).visit(ctx.map_element().test(0)) valor = super(GramaticaExtVisitor,self).visit(ctx.map_element().test(1)) nodo.valor[indice.valor] = valor if ctx.map_element() != None and ctx.map_element().submap_element() != None: for el in ctx.map_element().submap_element(): indice = super(GramaticaExtVisitor,self).visit(el.test(0)) valor = super(GramaticaExtVisitor,self).visit(el.test(1)) nodo.valor[indice.valor] = valor return nodo def visitIterable_tuple(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.test(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.test(1)) nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "TUPLE" nodo.valor = (valorI,valorD) return nodo def visitIterable_generate(self, ctx): valor = super(GramaticaExtVisitor,self).visit(ctx.test()) if valor.tipo == "INTEGER": nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "LIST" nodo.valor = [] for x in xrange(valor.valor): tmp = Nodo() tmp.tipo = "INTEGER" tmp.valor = x nodo.valor.append(tmp) return nodo elif valor.tipo == "STRING": nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "LIST" nodo.valor = [] for x in valor.valor: tmp = Nodo() tmp.valor = x tmp.tipo = "STRING" nodo.valor.append(tmp) return nodo else: ln = -1 self.raiseError(ln, 'Error en el generador, este debe ser de tipo cadena o entero', "non-iterable") def visitIterable_filter(self, ctx): iterab = super(GramaticaExtVisitor,self).visit(ctx.iterable()) if iterab == None: ln = -1 self.raiseError(ln, 'Error al evaluar el iterador', "iterator-eval") if iterab.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El objeto especificado no es de tipo iterable', "iterable-expected") if iterab.subtipo == "TUPLE": ln = -1 self.raiseError(ln, 'No es posible realizar un recorrido sobre una tupla', "iterable-tuple") filtrada = None if iterab.subtipo == "LIST": filtrada = [] else: filtrada = {} self.tablaDeSimbolosActual = TablaSimbolos(self.tablaDeSimbolosActual,self.tablaDeSimbolosActual.contexto) for tmp in iterab.valor: ac = None ty = None if iterab.subtipo == "LIST": ac = tmp.valor ty = tmp.tipo else: ac = iterab.valor[tmp].valor ty = iterab.valor[tmp].tipo simbolo = Simbolo(ctx.lambda_test().NAME(),ty,ac) self.tablaDeSimbolosActual.agregarSimbolo(simbolo.nombre, simbolo) res = super(GramaticaExtVisitor,self).visit(ctx.lambda_test().test()) if res.tipo != "BOOL": ln = -1 self.raiseError(ln, 'No es posible filtrar bajo la funcion especificada', "lambda-filter-error") if res.valor == True and iterab.subtipo == "LIST": filtrada.append(tmp) elif res.valor == True and iterab.subtipo =="MAP": filtrada[tmp] = iterab.valor[tmp] self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla() nodo = Nodo() nodo.subtipo = iterab.subtipo nodo.tipo = "ITERATOR" nodo.valor = filtrada print(nodo) return nodo def visitIterable_partition(self, ctx): pass def visitIterable_name(self,ctx): valor = self.tablaDeSimbolosActual.resolver(ctx.NAME()) if valor == None: ln = -1 self.raiseError(ln, 'El simbolo no se ha encontrado', ctx.NAME()) if valor.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El nombre no es de tipo iterador', ctx.NAME()) nodo = Nodo() nodo.tipo = valor.tipo nodo.subtipo = valor.subtipo nodo.valor = valor.valor return nodo def unirIterables(self,iterab1,iterab2): if iterab1 == None or iterab2 == None: ln = -1 self.raiseError(ln, "No se han proporcionado elementos para operar", "operators-expected") if iterab1.tipo != "ITERATOR" or iterab2.tipo != "ITERATOR": ln = -1 self.raiseError(ln, "Se han proporcionado tipos no iterables", "iterable-expected") if iterab1.subtipo == "MAP" or iterab2.subtipo == "MAP": if iterab1.subtipo == "MAP" and iterab2.subtipo == "MAP": nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "MAP" nodo.valor = {} for k in iterab2.valor: nodo.valor[k] = iterab2.valor[k] for k in iterab1.valor: nodo.valor[k] = iterab1.valor[k] return nodo elif iterab1.subtipo == "TUPLE" and iterab2.subtipo == "MAP": nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "MAP" nodo.valor = iterab2.valor nodo.valor[iterab1.valor[0].valor] = iterab1.valor[1] return nodo else: ln = -1 self.raiseError(ln, "No es posible concatenar un mapa con algun otro iterable", "tuple,map-expected") nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "LIST" nodo.valor = [] for k in iterab1.valor: nodo.valor.append(k) for k in iterab2.valor: nodo.valor.append(k) return nodo def visitIterable_addition(self,ctx): vl = super(GramaticaExtVisitor,self).visit(ctx.iterable(0)) iterab = super(GramaticaExtVisitor,self).visit(ctx.iterable(1)) if iterab == None or vl == None: ln = -1 self.raiseError(ln, "No se han proporcionado elementos para operar", "operators-expected") if iterab.tipo != "ITERATOR": ln = -1 self.raiseError(ln, "No es posible realizar esta operacion sobre un elemento no iterable", "iterable-expected") if vl.tipo == "ITERATOR": return self.unirIterables(vl, iterab) if iterab.tipo == "MAP": ln = -1 self.raiseError(ln, "No es posible agregar ese elemento en un mapa", "tuple,map-expected") nodo = Nodo() nodo.tipo = "ITERATOR" nodo.subtipo = "LIST" nodo.valor = [vl] + iterab.valor return nodo # # # # #SECCION DE COMPARACIONES Y TEST LOGICOS # # # # def visitTestAnd(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.test(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.test(1)) nodo = Nodo() print(valorI) print(valorD) if valorI.tipo == "BOOL" and valorD.tipo == "BOOL": nodo.tipo = "BOOL" nodo.valor = valorI.valor and valorD.valor print(nodo.valor) else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion and-test") return nodo def visitTestOr(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.test(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.test(1)) nodo = Nodo() if valorI.tipo == "BOOL" and valorD.tipo == "BOOL": nodo.tipo = "BOOL" nodo.valor = valorI.valor or valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion or-test") return nodo def visitTestNot(self, ctx): valor = super(GramaticaExtVisitor,self).visit(ctx.test(0)) nodo = Nodo() if valor.tipo == "BOOL": nodo.tipo = "BOOL" nodo.valor = not valor.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion not-test") return nodo def visitTestExprComp(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() nodo.tipo = "BOOL" op = ctx.comp_op().getText() if valorI.tipo == "ITERATOR" or valorD.tipo == "ITERATOR": ln = -1 self.raiseError(ln, "No es posible realizar este tipo de operacion con elementos iterables", "primitive-expected") if op == "<": nodo.valor = valorI.valor < valorD.valor elif op == ">": nodo.valor = valorI.valor > valorD.valor elif op == "==": nodo.valor = valorI.valor == valorD.valor elif op == ">=": nodo.valor = valorI.valor >= valorD.valor elif op == "<=": nodo.valor = valorI.valor <= valorD.valor elif op == "<>": nodo.valor = valorI.valor <> valorD.valor elif op == "!=": print(valorI) print(valorD) nodo.valor = valorI.valor != valorD.valor return nodo def visitTest_iterable_in(self,ctx): vl = super(GramaticaExtVisitor,self).visit(ctx.test()) iterab = super(GramaticaExtVisitor,self).visit(ctx.iterable()) if iterab == None or vl == None: ln = -1 self.raiseError(ln, "No se han proporcionado elementos para operar", "operators-expected") if iterab.tipo != "ITERATOR": ln = -1 self.raiseError(ln, "No es posible realizar esta operacion sobre un elemento no iterable", "iterable-expected") nodo = Nodo() nodo.tipo = "BOOL" nodo.valor = False for t in iterab: if t.tipo == vl.tipo and t.valor == vl.valor: nodo.valor = True return nodo return nodo # # # # #SECCION DE OPERADORES ARITMETICOS, SE DEBE TENER EN CUENTA EL TIPO DE OPERANDOS PARA ESTA PARTE # # # # def visitExprPower(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if self.numerico(valorI) and self.numerico(valorD): if valorI.tipo == "FLOAT" or valorD.tipo == "FLOAT": nodo.tipo = "FLOAT" else: nodo.tipo = "INTEGER" nodo.valor = valorI.valor ** valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion potencia") return nodo def visitExprMultiply(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if self.numerico(valorI) and self.numerico(valorD): if valorI.tipo == "FLOAT" or valorD.tipo == "FLOAT": nodo.tipo = "FLOAT" else: nodo.tipo = "INTEGER" nodo.valor = valorI.valor * valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion multiplicacion") return nodo def visitExprDivision(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if self.numerico(valorI) and self.numerico(valorD): if valorI.tipo == "FLOAT" or valorD.tipo == "FLOAT": nodo.tipo = "FLOAT" else: nodo.tipo = "INTEGER" nodo.valor = valorI.valor / valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion division") return nodo def visitExprModule(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor % valorD.valor print(str(valorI)+" : "+str(valorD)); else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion modulo") return nodo def visitExprPlus(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if self.numerico(valorI) and self.numerico(valorD): if valorI.tipo == "FLOAT" or valorD.tipo == "FLOAT": nodo.tipo = "FLOAT" else: nodo.tipo = "INTEGER" nodo.valor = valorI.valor + valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion suma") return nodo def visitExprMinus(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if self.numerico(valorI) and self.numerico(valorD): if valorI.tipo == "FLOAT" or valorD.tipo == "FLOAT": nodo.tipo = "FLOAT" else: nodo.tipo = "INTEGER" nodo.valor = valorI.valor - valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion resta") return nodo def visitExprShiftLeft(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor << valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion shift-left") return nodo def visitExprShiftRight(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor >> valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion shift-right") return nodo def visitExprAnd(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor & valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion bit-and") return nodo def visitExprOr(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor | valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion bit-or") return nodo def visitExprXor(self, ctx): valorI = super(GramaticaExtVisitor,self).visit(ctx.expr(0)) valorD = super(GramaticaExtVisitor,self).visit(ctx.expr(1)) nodo = Nodo() if valorI.tipo == "INTEGER" or valorD.tipo == "INTEGER": nodo.tipo = "INTEGER" nodo.valor = valorI.valor ^ valorD.valor else: ln = -1 self.raiseError(ln, 'Error en los operandos', "Operacion bit-xor") return nodo # # # # #LISTENER PARA LOS VALORES ATOMICOS # # # # def visitAtomName(self, ctx): nodo = Nodo() valor = self.evaluarSimbolo(ctx.NAME()) nodo.tipo = valor.tipo nodo.valor = valor.valor nodo.subtipo = valor.subtipo print("se ha solicitado: "+str(ctx.NAME())+" con valor: "+str(nodo)) print("en :"+str(self.tablaDeSimbolosActual)) #self.pilaValores.append(nodo) return nodo def visitAtomString(self, ctx): nodo = Nodo() nodo.valor = str(ctx.STRING()) nodo.valor = nodo.valor[1:len(nodo.valor)-1] nodo.tipo = "STRING" #self.pilaValores.append(nodo) return nodo def visitAtomNone(self, ctx): nodo = Nodo() nodo.valor = None nodo.tipo = "NONE" #self.pilaValores.append(nodo) return nodo def visitAtomTrue(self, ctx): nodo = Nodo() nodo.valor = True nodo.tipo = "BOOL" #self.pilaValores.append(nodo) return nodo def visitAtomFalse(self, ctx): nodo = Nodo() nodo.valor = False nodo.tipo = "BOOL" #self.pilaValores.append(nodo) return nodo def visitAtomFuncCall(self, ctx): return self.evaluarFuncion(ctx) def visitAtomIterableAccess(self, ctx): simbolo = self.tablaDeSimbolosActual.resolver(ctx.NAME()) if simbolo == None: ln = -1 self.raiseError(ln, 'Simbolo no encontrado', ctx.NAME()) elif simbolo.tipo != "ITERATOR": ln = -1 self.raiseError(ln, 'El objeto no es interable', ctx.NAME()) indice = super(GramaticaExtVisitor,self).visit(ctx.test()) return simbolo.valor[indice.valor] def visitAtomIterableDef(self, ctx): return super(GramaticaExtVisitor,self).visit(ctx.iterable()) # # # # #LISTENER PARA LOS VALORES NUMERICOS # # # # def visitNumberInteger(self, ctx): valor = int(ctx.integer().getText()) nodo = Nodo() nodo.valor = valor nodo.tipo = "INTEGER" #self.pilaValores.append(nodo) return nodo def visitNumberFloat(self, ctx): valor = float(ctx.FLOAT_NUMBER().getText()) nodo = Nodo() nodo.valor = valor nodo.tipo = "FLOAT" #self.pilaValores.append(nodo) return nodo # # # # # UTILIDADES VARIAS # # # # def evaluarSimbolo(self,nombre): valor = self.tablaDeSimbolosActual.resolver(nombre) if valor == None: ln = -1 self.raiseError(ln, 'Error simbolo no encontrado', nombre) return valor def numerico(self,nodo): return nodo.tipo == "INTEGER" or nodo.tipo == "FLOAT" def evaluarInstrucciones(self,instrucciones): for inst in instrucciones: ret = super(GramaticaExtVisitor,self).visit(inst) if inst.flow_stmt() != None and inst.flow_stmt().return_stmt() != None: return ret elif ret != self._NONE: print(ret) return ret return self._NONE def evaluarArgumento(self,arg): valor = super(GramaticaExtVisitor,self).visit(arg) return (valor.tipo,valor.valor) def evaluarFuncion(self,ctx): simbolo = self.tablaDeSimbolosActual.resolver(ctx.NAME()) if simbolo == None: ln = -1 self.raiseError(ln, 'Error en el simbolo', ctx.NAME()) if simbolo.tipo != "FUNCION": ln = -1 self.raiseError(ln,'Error, el simbolo no puede ser evaluado como una funcion',ctx.NAME()) parametros = [] if ctx.parameters() != None : parametros.append(ctx.parameters().test()) if len( ctx.parameters().sub_parameters() ) > 0: for param in ctx.parameters().sub_parameters(): parametros.append(param.test()) if len(parametros) != len(simbolo.argumentos ): ln = -1 self.raiseError(ln, "Error en la cantidad de parametros", ctx.NAME()) nuevaTablaSimbolos = TablaSimbolos(None,self.tablaDeSimbolosActual.contexto+1) for i in xrange(0,len(parametros)): argument = self.evaluarArgumento(parametros[i]) #print("argumento: "+str(argument)) simboloNuevo = Simbolo(simbolo.argumentos[i],argument[0],argument[1]) nuevaTablaSimbolos.agregarSimbolo(simbolo.argumentos[i], simboloNuevo) nuevaTablaSimbolos.padre = self.tablaDeSimbolosActual self.tablaDeSimbolosActual = nuevaTablaSimbolos ret = super(GramaticaExtVisitor,self).visit(simbolo.valor) self.tablaDeSimbolosActual = self.tablaDeSimbolosActual.destruirTabla() print("Evaluando: "+str(ctx.NAME())+" con valor de retorno "+str(ret)) if ret != self._NONE: return ret; return self._NONE def raiseError(self,ln,msg,smb): ret = "Airi dice: Error en la linea "+str(ln)+" se ha producido el siguiente error: "+str(msg)+" con el simbolo: "+str(smb)+", por favor revise la entrada" raise RuntimeError(ret)