Example #1
0
 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
Example #2
0
 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
Example #3
0
    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
Example #4
0
 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()
Example #5
0
 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()
Example #6
0
 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
Example #7
0
    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()
Example #8
0
File: main.py Project: rv0lt/PDL
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 = (
Example #9
0
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()
Example #10
0
 def __init__(self):
     self.contextoActual = 0
     self.pilaValores = collections.deque()
     self.tablaDeSimbolosActual = TablaSimbolos(None,0)
Example #11
0
 def __init__(self, an):
     #super(GramaticaExtListener,self)
     self.tablaDeSimbolosActual = TablaSimbolos(None, 0)
     self.pilaValores = collections.deque()
     self.an = an
Example #12
0
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)
Example #13
0
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()
Example #14
0
 def __init__(self):
     self.contextoActual = 0
     self.pilaValores = collections.deque()
     self.tablaDeSimbolosActual = TablaSimbolos(None, 0)
Example #15
0
 def __init__(self,an):
     #super(GramaticaExtListener,self)
     self.tablaDeSimbolosActual = TablaSimbolos(None,0)
     self.pilaValores = collections.deque()  
     self.an = an
Example #16
0
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)