Ejemplo n.º 1
0
 def visitarBinaryOp(self, binaryOp):
     binaryOp.valorUno.accept(self)
     binaryOp.valorDos.accept(self)
     if binaryOp.valorUno.tipo != 'null' and binaryOp.valorDos.tipo != 'null' and binaryOp.valorUno.tipo != binaryOp.valorDos.tipo:
         raise SemanticError(
             'Error semantico, operacion binaria entre tipos incompatibles, en metodo: '
             + self.metodoActual.nombre)
     if binaryOp.operador in ['==', '!=']:
         pass
     elif binaryOp.valorUno.tipo == 'null' or binaryOp.valorDos.tipo == 'null':
         raise SemanticError(
             'Error semantico, operacion binaria entre tipos incompatibles, en metodo: '
             + self.metodoActual.nombre)
     elif binaryOp.operador in ['&&', '||']:
         if binaryOp.valorUno.tipo != 'boolean':
             raise SemanticError(
                 'Error semantico, operacion binaria entre tipos incompatibles, en metodo: '
                 + self.metodoActual.nombre)
     else:
         if binaryOp.operador == '+':
             if binaryOp.valorUno.tipo != 'string' and binaryOp.valorUno.tipo != 'int':
                 raise SemanticError(
                     'Error semantico, operacion binaria entre tipos incompatibles, en metodo: '
                     + self.metodoActual.nombre)
         elif binaryOp.valorUno.tipo != 'int':
             raise SemanticError(
                 'Error semantico, operacion binaria entre tipos incompatibles, en metodo: '
                 + self.metodoActual.nombre)
     if binaryOp.operador in ['==', '!=', '<=', '<', '>', '>=']:
         binaryOp.tipo = 'boolean'
     else:
         binaryOp.tipo = binaryOp.valorUno.tipo
Ejemplo n.º 2
0
 def visitarLocation(self, location):
     if location.tipoLocacion == 0:
         location.entrada = self.tablaActual.buscar(location.valorUno)
         if location.entrada.clase == 'metodo':
             raise SemanticError('Error semantico, Locacion invalida: ' +
                                 location.entrada.nombre + ' en metodo: ' +
                                 self.metodoActual.nombre)
         location.tabla = location.entrada.tabla
         location.tipo = location.entrada.tipo
     elif location.tipoLocacion == 1:
         location.valorUno.accept(self)
         location.entrada = self.tablaPrincipal.buscar(
             location.valorUno.tipo).tabla.buscar(location.valorDos)
         location.tabla = location.entrada.tabla
         if location.entrada.clase == 'metodo':
             raise SemanticError('Error semantico, Locacion invalida: ' +
                                 location.entrada.nombre + ' en metodo: ' +
                                 self.metodoActual.nombre)
         location.tipo = location.entrada.tipo
     elif location.tipoLocacion == 2:
         location.valorUno.accept(self)
         location.valorDos.accept(self)
         if location.valorDos.tipo != 'int':
             raise SemanticError(
                 'Error semantico, posicion dentro del vector debe ser int en metodo: '
                 + self.metodoActual.nombre)
         if location.valorUno.tipo[-2:] != '[]':
             raise SemanticError(
                 'Error semantico, intentando accesar a posicion dentro de objeto que no es vector en metodo: '
                 + self.metodoActual.nombre)
         location.tipo = location.valorUno.tipo[:-2]
Ejemplo n.º 3
0
 def visitarIf(self, i):
     i.condicion.accept(self)
     if not (i.condicion.tipo == 'boolean'):
         raise SemanticError(
             'Error semantico, condicion de if no es booleana, en metodo: '
             + self.metodoActual.nombre)
     if isinstance(i.bloqueIf, tuple):
         raise SemanticError(
             'Error semantico, declaracion inocua como unico statement de un if, en metodo: '
             + self.metodoActual.nombre)
     i.bloqueIf.esFieldSt()
     if i.bloqueIf.esFieldS:
         raise SemanticError(
             'Error semantico, declaracion inocua como unico statement de un if, en metodo: '
             + self.metodoActual.nombre)
     i.bloqueIf.accept(self)
     if i.tieneElse:
         if isinstance(i.bloqueElse, tuple):
             raise SemanticError(
                 'Error semantico, declaracion inocua como unico statement de un else, en metodo: '
                 + self.metodoActual.nombre)
         i.bloqueElse.esFieldSt()
         if i.bloqueElse.esFieldS:
             raise SemanticError(
                 'Error semantico, declaracion inocua como unico statement de un else, en metodo: '
                 + self.metodoActual.nombre)
         i.bloqueElse.accept(self)
     i.tieneReturn = i.bloqueIf.tieneReturn and i.tieneElse and i.bloqueElse.tieneReturn
Ejemplo n.º 4
0
 def visitarUnaryOp(self, unaryOp):
     unaryOp.valor.accept(self)
     if unaryOp.operador == '!' and unaryOp.valor.tipo != 'boolean':
         raise SemanticError(
             'Error semantico, negacion de valor que no es booleano, en metodo: '
             + self.metodoActual.nombre)
     elif unaryOp.operador == '-' and unaryOp.valor.tipo != 'int':
         raise SemanticError(
             'Error semantico, multiplicacion por -1 de valor que no es int, en metodo: '
             + self.metodoActual.nombre)
     unaryOp.tipo = unaryOp.valor.tipo
Ejemplo n.º 5
0
    def visitarNew(self, new):
        if new.tipoNew == 0:
            self.tablaPrincipal.buscar(new.valorUno)
            if new.valorUno == 'Library':
                raise SemanticError('Error semantico, llamado a tipo Library')
            new.tipo = new.valorUno

        else:
            new.valorUno.accept(self)
            new.valorDos.accept(self)
            if new.valorDos.tipo != 'int':
                raise SemanticError(
                    'Error semantico, tamano de arreglo no es entero, en metodo: '
                    + self.metodoActual.nombre)
            new.tipo = new.valorUno.tipo + '[]'
Ejemplo n.º 6
0
 def visitarVirtualCall(self, virtualCall):
     if virtualCall.expresion:
         virtualCall.valorExpresion.accept(self)
         if virtualCall.valorExpresion.tipo == 'class':
             virtualCall.clase = virtualCall.valorExpresion.valorUno
             virtualCall.estatico = True
             self.visitarStaticCall(virtualCall)
             return None
         virtualCall.entrada = self.tablaPrincipal.buscar(
             virtualCall.valorExpresion.tipo).tabla.buscar(
                 virtualCall.nombreFuncion)
         virtualCall.estatico = False
     else:
         virtualCall.estatico = False
         virtualCall.entrada = self.metodoActual.tabla.padre.buscar(
             virtualCall.nombreFuncion)
     for expr in virtualCall.parametros:
         expr.accept(self)
     for parametro, expr in zip(virtualCall.entrada.informacion,
                                virtualCall.parametros):
         if not (self.esHeredero(expr.tipo, parametro.tipo.tipo)):
             raise SemanticError(
                 'Error semantico, parametros no corresponden en llamado a metodo: '
                 + virtualCall.nombreFuncion)
     virtualCall.tipo = virtualCall.entrada.tipo
Ejemplo n.º 7
0
 def buscarCampoRepetido(self, nombre):
     if nombre in self.tabla:
         raise SemanticError('Error semantico, campo redeclarado: ' +
                             (nombre))
     else:
         if self.padre != None:
             self.padre.buscarCampoRepetido(nombre)
Ejemplo n.º 8
0
 def visitarLength(self, length):
     length.valor.accept(self)
     if (length.valor.tipo[-2:] != '[]') and (length.valor.tipo !=
                                              'string'):
         raise SemanticError(
             'Error semantico, intentando acceder a longitud de objeto que no es arreglo, en metodo: '
             + self.metodoActual.nombre)
     length.tipo = 'int'
Ejemplo n.º 9
0
 def buscarFuncionRedefinida(self, entradaMetodo):
     if entradaMetodo.nombre in self.tabla:
         entradaPosible = self.tabla[entradaMetodo.nombre]
         if entradaPosible.clase != 'metodo' or entradaPosible.tipo != entradaMetodo.tipo or len(
                 entradaMetodo.informacion) != len(
                     entradaPosible.informacion):
             raise SemanticError(
                 'Error semantico, funcion redefinida erroneamente: ' +
                 (entradaMetodo.nombre))
         for formal1, formal2 in zip(entradaMetodo.informacion,
                                     entradaPosible.informacion):
             if formal1.tipo.tipo != formal2.tipo.tipo:
                 raise SemanticError(
                     'Error semantico, funcion redefinida erroneamente: ' +
                     (entradaMetodo.nombre))
     elif self.padre != None:
         self.padre.buscarFuncionRedefinida(entradaMetodo)
Ejemplo n.º 10
0
 def visitarAssigment(self, assigment):
     assigment.location.accept(self)
     tablaTemp = self.tablaActual
     if assigment.inicio:
         self.tablaActual = self.tablaActual.padre
     assigment.expr.accept(self)
     self.tablaActual = tablaTemp
     if not (self.esHeredero(assigment.expr.tipo, assigment.location.tipo)):
         if isinstance(assigment.location.valorUno, str):
             raise SemanticError(
                 'Error semantico, asignacion de tipo erronea, en metodo: '
                 + self.metodoActual.nombre + ' locacion: ' +
                 assigment.location.valorUno)
         else:
             raise SemanticError(
                 'Error semantico, asignacion de tipo erronea, en metodo: '
                 + self.metodoActual.nombre + ' entre tipos ' +
                 assigment.expr.tipo + ' y ' + assigment.location.tipo)
Ejemplo n.º 11
0
 def visitarReturn(self, ret):
     if ret.retorno != None:
         ret.retorno.accept(self)
         if not (self.esHeredero(ret.retorno.tipo,
                                 self.metodoActual.tipoRetorno.tipo)):
             raise SemanticError(
                 'Error semantico, tipo de retorno invalido, en metodo: ' +
                 self.metodoActual.nombre)
         ret.tieneReturn = True
Ejemplo n.º 12
0
 def buscar(self, nombre):
     if nombre in self.tabla:
         return self.tabla[nombre]
     else:
         if self.padre != None:
             return self.padre.buscar(nombre)
         raise SemanticError(
             'Error semantico, identificador no declarado o tipo incompatible: '
             + (nombre))
Ejemplo n.º 13
0
 def visitarProgram(self, program):
     for clase in program:
         self.generarTablaClase(clase)
     for clase in program:
         self.generarMetodosYCampos(clase)
     for clase in program:
         clase.accept(self)
     if not (self.main):
         raise SemanticError(
             'Error semantico, el programa debe contener un unico main de la forma: static void main (string[] args) { ... }'
         )
Ejemplo n.º 14
0
 def visitarWhile(self, whi):
     whi.condicion.accept(self)
     if not (whi.condicion.tipo == 'boolean'):
         raise SemanticError(
             'Error semantico, condicion de while no es booleana, en metodo: '
             + self.metodoActual.nombre)
     if isinstance(whi.bloque, tuple):
         raise SemanticError(
             'Error semantico, declaracion inocua como unico statement de un while, en metodo: '
             + self.metodoActual.nombre)
     whi.bloque.esFieldSt()
     if whi.bloque.esFieldS:
         raise SemanticError(
             'Error semantico, declaracion inocua como unico statement de un while, en metodo: '
             + self.metodoActual.nombre)
     whileTemp = self.enWhile
     self.enWhile = True
     whi.bloque.accept(self)
     self.enWhile = whileTemp
     whi.tieneReturn = whi.bloque.tieneReturn
Ejemplo n.º 15
0
 def visitarMethod(self, metodo):
     tablaTemp = self.tablaActual
     if metodo.estatico:
         self.tablaActual = self.tablaPrincipal.buscar(tablaTemp.nombre +
                                                       '.' +
                                                       metodo.nombre).tabla
     else:
         self.tablaActual = self.tablaActual.buscar(metodo.nombre).tabla
     self.metodoActual = metodo
     metodo.tabla = self.tablaActual
     for formal in metodo.formales:
         formal.accept(self)
     if metodo.nombre == 'main':
         if not (metodo.estatico) or not (
                 metodo.tipoRetorno.tipo
                 == None) or not (len(metodo.formales)
                                  == 1) or not (metodo.formales[0].tipo.tipo
                                                == 'string[]') or self.main:
             raise SemanticError(
                 'Error semantico, el programa debe contener un unico main de la forma: static void main (string[] args) { ... }'
             )
         self.main = True
     metodo.bloque.accept(self)
     if metodo.tipoRetorno.tipo == None:
         for declaracion in metodo.bloque.lista:
             if declaracion.tieneReturn:
                 raise SemanticError(
                     'Error semantico, retorno no permitido en metodo: ' +
                     metodo.nombre)
     else:
         termino = False
         for declaracion in metodo.bloque.lista:
             if declaracion.tieneReturn:
                 termino = True
                 break
         if not (termino) and metodo.tabla.nombre[:7] != 'Library':
             raise SemanticError(
                 'Error semantico, fin de metodo encontrado sin retornar, en metodo: '
                 + metodo.nombre)
     self.tablaActual = tablaTemp
Ejemplo n.º 16
0
 def visitarStaticCall(self, staticCall):
     staticCall.entrada = self.tablaPrincipal.buscar(
         staticCall.clase + '.' + staticCall.nombreFuncion)
     staticCall.tabla = staticCall.entrada.tabla
     for expr in staticCall.parametros:
         expr.accept(self)
     for parametro, expr in zip(staticCall.entrada.informacion,
                                staticCall.parametros):
         if not (self.esHeredero(expr.tipo, parametro.tipo.tipo)):
             raise SemanticError(
                 'Error semantico, parametros no corresponden en llamado a metodo: '
                 + staticCall.nombreFuncion)
     staticCall.tipo = staticCall.entrada.tipo
Ejemplo n.º 17
0
 def visitarBloque(self, bloque):
     tablaTemp = self.tablaActual
     self.tablaActual = Tabla('', self.tablaActual, 'bloque')
     tablaTemp.agregarHijo(self.tablaActual)
     bloque.tabla = self.tablaActual
     termino = False
     inicio = True
     for declaracion in bloque.lista:
         declaracion.accept(self)
         if declaracion.tieneReturn:
             termino = True
         declaracion.esFieldSt()
         if declaracion.esFieldS or declaracion.inicio:
             if not (inicio):
                 raise SemanticError(
                     'Error semantico, campo declarado tardiamente: ' +
                     declaracion.campo.nombre)
         else:
             inicio = False
     bloque.tieneReturn = termino
     self.tablaActual = tablaTemp
Ejemplo n.º 18
0
 def buscarHijo(self, nombre):
     for objeto in self.hijos:
         if objeto.nombre == nombre:
             return objeto
     raise SemanticError('Error semantico, identificador no declarado: ' +
                         (nombre))
Ejemplo n.º 19
0
 def visitarContinue(self, cont):
     if not (self.enWhile):
         raise SemanticError(
             'Error semantico, continue/break no permitido en metodo: ' +
             self.metodoActual.nombre)
     tablaTemp = self.tablaActual
Ejemplo n.º 20
0
 def visitarThis(self, this):
     if self.metodoActual.estatico:
         raise SemanticError('Error semantico, llamada a this en metodo: ' +
                             self.metodoActual.nombre + ' que es estatico')
     this.tipo = self.metodoActual.tabla.padre.nombre
Ejemplo n.º 21
0
 def agregar(self, entrada):
     if entrada.nombre in self.tabla:
         raise SemanticError('Error semantico, identificador redefinido: ' +
                             (entrada.nombre))
     self.tabla[entrada.nombre] = entrada
Ejemplo n.º 22
0
 def visitarType(self, type):
     if not (type.primitivo):
         self.tablaPrincipal.buscar(type.nombre)
     if type.nombre == 'Library':
         raise SemanticError('Error semantico, llamado a tipo Library')