def recorrer_entrada(self, cadena, tipos, pila): self.inicializar_reglas() while self.aceptacion == False: self.fila = self.regresa_tipo(pila.top()) self.columna = self.regresa_tipo(tipos[self.contador]) self.accion = self.tabla[self.fila, self.columna] if self.accion == -1: print("Cadena aceptada") self.aceptacion = True break if self.accion > 0: pila.push(tipos[self.contador]) pila.push(self.accion) self.contador = self.contador + 1 elif self.accion < 0: self.accion = -self.accion self.accion = self.accion - 1 for i in range(self.numero_elementos[self.accion - 1] * 2): pila.pop() self.fila = pila.top() pila.push(self.reglas[self.accion - 1]) self.columna = pila.top() self.accion = self.tabla[self.fila, self.regresa_tipo(self.columna)] pila.push(self.accion) else: print("Cadena no valida") self.aceptacion = True Hi
class Sintactico(): def __init__(self, size): self.pila = Pila() self.pila.push('$') self.pila.push('0') self.columna = 0 self.cantidad = size self.accion = "" def comparar(self, token): if (valores[token]): self.accion = matriz[int(self.pila.top())][int(valores[token])] print('Pila: ', self.pila.get()) print('Token: ', token) if (self.accion == -1): print('Cadena valida') elif (self.accion > 0): self.pila.push(self.accion) print('Accion: PUSH') print('\n') elif (self.accion < 0): self.pila.pop(reglas[self.accion]['cantidad']) self.pila.push(matriz[int( self.pila.top())][reglas[self.accion]['columna']]) print('Accion: POP %d elementos' % reglas[self.accion]['cantidad']) print('Accion: PUSH de la regla') print('\n') self.comparar('$') else: print('Invalida') exit()
def postorden(cadena): save="" if cadena is not None: pila=Pila() print "la operacion a efectuar es: "+cadena.operacion for c in cadena.operacion: if c =="*": A=int(pila.pop().valor) B=int(pila.pop().valor) C=A*B print " se multiplico "+str(B)+" por "+str(A) pila.push(str(C)) elif c =="+": A=int(pila.pop().valor) B=int(pila.pop().valor) C=A+B print " se sumo "+str(B)+" mas "+str(A) pila.push(str(C)) elif c =="-": A=int(pila.pop().valor) B=int(pila.pop().valor) C=B-A print " se resto "+str(B)+" menos "+str(A) pila.push(str(C)) elif c=="0" or c=="1" or c=="2" or c=="3" or c=="4" or c=="5" or c=="6" or c=="7" or c=="8" or c=="9" : save=save+c print " se cargo "+c+" a la pila " else: if save!="": pila.push(save) save="" print "resultado="+pila.pop().valor else: print "la cola parece estar vacia"
class Sintactico(): def __init__(self,size): self.pila = Pila() self.pila.push('$') self.pila.push('0') self.columna = 0 self.cantidad = size self.accion = "" self.list_tmp = list() self.arbol = [] def comparar(self,token,valor): if(valores[token]): self.accion = matriz[int(self.pila.top())][int(valores[token])] print('Pila: ', self.pila.get()) print('Token: ', token) if(self.accion == -1): print('Cadena valida\n') print('==== Arbol ====') self.arbol = self.arbol[::-1] for item in self.arbol: item.list = item.list[::-1] print(item.regla,'==> ',item.list) elif(self.accion > 0): self.pila.push(self.accion) self.list_tmp.append(valor) print('Accion: PUSH') print('\n') elif(self.accion < 0): self.pila.pop(reglas[self.accion]['cantidad']) self.pila.push(matriz[int(self.pila.top())][reglas[self.accion]['columna']]) print('-----GENERA REGLA-----') print('Accion: POP %d elementos'%reglas[self.accion]['cantidad']) print('Accion: PUSH de la regla') print('Nombre: ', reglas[self.accion]['nombre']) print('\n') list_aux = [] if(reglas[self.accion]['cantidad'] > 0): print('Lista:' ,self.list_tmp) aux = reglas[self.accion]['cantidad'] for i in range(aux): valor2 = self.list_tmp.pop(-1) list_aux.append(valor2) self.arbol.append(nodo(reglas[self.accion]['nombre'], reglas[self.accion]['regla'], list_aux)) self.list_tmp.append(reglas[self.accion]['regla']) self.comparar(token,valor) else: print('Invalida') exit()
def test_pop(self): "Chequea que el elemento popeado sea efectivamente el tope anterior de la pila" pila1=Pila() pila1.body=[1,2,3] tope=pila1.body[0] salida=pila1.pop() self.assertEqual(tope,salida) pila1.body=[] salida=pila1.pop() self.assertEqual(None,salida)
class Semantico(): def __init__(self): self.tmp_index = 0 self.pila = Pila() self.codigo = [] self.archivo = 'codigo.3ac' def gen_temp(self): tmp = "_tmp" + str(self.tmp_index) self.tmp_index += 1 return tmp def push(self, item): self.pila.push(item) def pop(self): return self.pila.pop() def agregar_linea_3ac(self, linea): self.codigo.append(linea) def generar_archivo_3ac(self): with open(self.archivo, 'w') as f: for line in self.codigo: f.write('{}\n'.format(line))
def recorrer_entrada(self, cadena, tipos, pila): self.inicializar_reglas() while self.aceptacion == False: print("Cadena: " + str(cadena[self.contador])) self.fila = self.regresa_tipo(pila.top()) self.columna = self.regresa_tipo(tipos[self.contador]) self.accion = self.tabla[self.fila, self.columna] print("Fila: " + str(self.fila) + " pila_top: " + str(pila.top())) print("Columna: " + str(self.columna) + " tipos__: " + str(tipos[self.contador])) print("Accion: " + str(self.accion)) if self.accion == -1: print("Cadena aceptada") self.aceptacion = True break if self.accion > 0: pila.push(tipos[self.contador]) pila.push(self.accion) self.contador = self.contador + 1 pila.muestra() print("\n----------------\n\n") #if self.contador == 5: # self.aceptacion = True elif self.accion < 0: self.accion = -self.accion self.accion = self.accion - 1 for i in range(self.numero_elementos[self.accion - 1] * 2): pila.pop() self.fila = pila.top() pila.push(self.reglas[self.accion - 1]) self.columna = pila.top() self.accion = self.tabla[self.fila, self.regresa_tipo(self.columna)] pila.push(self.accion) print("=====") pila.muestra() print("=====") # self.aceptacion = True else: print("Cadena no valida") self.aceptacion = True
class Sintactico(): def __init__(self, size): self.pila = Pila() self.pila.push('$') self.pila.push('0') self.columna = 0 self.cantidad = size self.accion = "" def comparar(self, token): if (valores[token]): self.accion = matriz[int(self.pila.top())][int(valores[token])] if (self.accion == -1): print('Cadena valida') elif (self.accion > 0): self.pila.push(self.accion) elif (self.accion < 0): self.pila.pop(reglas[self.accion]['cantidad']) self.pila.push(matriz[int( self.pila.top())][reglas[self.accion]['columna']]) self.comparar('$') else: print('Invalida') exit()
class avail: cubo_semantico = None def __init__(self): self.temp_booleano = 4000 self.temp_entero = 5000 self.temp_flotante = 6000 self.temp_dir = 7000 self.Bloque = 0 self.OPila = Pila() self.TPila = Pila() self.OpPila = Pila() self.salto = Pila() self.numCuad = 0 self.funcCuad = 0 self.cuad = [] self.DPila = Pila() self.IDPila = Pila() self.alcanceF = Pila() self.alcance = '' self.RT = '' self.cubo_semantico = { '=': { 'entero': { 'entero': 'entero', 'flotante': 'flotante' }, 'flotante': { 'entero': 'error', 'flotante': 'flotante' } }, '>': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '<': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '>=': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '<=': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '!=': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '==': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '+': { 'entero': { 'entero': 'entero', 'flotante': 'flotante' }, 'flotante': { 'entero': 'flotante', 'flotante': 'flotante' } }, '-': { 'entero': { 'entero': 'entero', 'flotante': 'flotante' }, 'flotante': { 'entero': 'flotante', 'flotante': 'flotante' } }, '*': { 'entero': { 'entero': 'entero', 'flotante': 'flotante' }, 'flotante': { 'entero': 'flotante', 'flotante': 'flotante' } }, '/': { 'entero': { 'entero': 'entero', 'flotante': 'flotante' }, 'flotante': { 'entero': 'flotante', 'flotante': 'flotante' } }, '$': { 'dir': { '-1': 'dir' } } } #regresa el tipo de la operacion def get_tipo(self, argOper, uno, dos): esperado = self.cubo_semantico.get(argOper) if esperado != None: esperado = esperado.get(uno) if esperado != None: esperado = esperado.get(dos) return esperado print 'error' #se crea un nuevo valor temporal en base al resultado del cubo semantico def get_temporal(self, argOper, uno, dos): tempoTipo = self.get_tipo(argOper, uno, dos) if tempoTipo == 'entero': res = self.temp_entero self.temp_entero += 1 elif tempoTipo == 'flotante': res = self.temp_flotante self.temp_flotante += 1 elif tempoTipo == 'bool': res = self.temp_booleano self.temp_booleano += 1 elif uno == 'dir': res = self.temp_dir self.temp_dir += 1 res += (self.Bloque * 10000) return [res, self.get_tipo(argOper, uno, dos)] #regresa el bloque actual def getBloque(self): return self.Bloque #resetea la memoria para el siguiente bloque def setBloque(self, Bloque): self.Bloque = Bloque self.temp_booleano = 4000 self.temp_entero = 5000 self.temp_flotante = 6000 self.temp_dir = 7000 #regresa la memoria necesaria para las temporales def get_temporal_dirs(self): return [(self.temp_booleano-4000), (self.temp_entero-5000), (self.temp_flotante-6000), (self.temp_dir-7000)] #si hay una expresion para resolver def expresion(self): if(self.OpPila.size() > 0): if(self.OpPila.peek() == '>' or self.OpPila.peek() == '<' or self.OpPila.peek() == '!=' or self.OpPila.peek() == '==' or self.OpPila.peek() == '<=' or self.OpPila.peek() == '>='): self.quad() #si hay una operacion se suma o resta def sum_res(self): if(self.OpPila.size() > 0): if(self.OpPila.peek() == '+' or self.OpPila.peek() == '-'): self.quad() #si hay una operacion de multiplicacion o division def mult_div(self): if(self.OpPila.size() > 0): if(self.OpPila.peek() == '*' or self.OpPila.peek() == '/'): self.quad() #crea una asignacion def asign(self, dato): if(self.OPila.size() > 0): self.numCuad += 1 cuads = [101, self.OPila.pop(), -1, dato] self.cuad.append(cuads) #saca uno de los valores de la temporal def rep_salto(self, primDir, dirInic): valT = self.OPila.pop() cuads = ['-', valT, primDir, valT] self.numCuad += 1 self.cuad.append(cuads) salto = self.salto.pop() aux = self.get_temporal('==', self.TPila.pop(), 'entero') cuads = ['==', valT, dirInic, aux[0]] self.numCuad += 1 self.cuad.append(cuads) cuads = ['GOTOF', aux[0], -1, salto] self.numCuad += 1 self.cuad.append(cuads) #al inicio de una condicion se crea un gotof y se almacena el num de cuadruplo en la pila de saltos def condicion(self): estCondic = self.OPila.pop() tipoCondicion = self.TPila.pop() if(tipoCondicion != "bool"): print "Error, el tipo no coincide" sys.error(0) else: cuads = ['GOTOF', estCondic, -1, -1] self.cuad.append(cuads) self.numCuad += 1 self.salto.push(self.numCuad) #al final de una condicion llena el ultimo goto que fue creado con el cuadruplo actual def condicion_inicio(self): if(self.salto.size() > 0): salto = self.salto.pop() - 1 cuads = self.cuad[salto] cuads[3] = self.numCuad self.cuad[salto] = cuads #si hay un else, se debe llenar el goto del if y crear un nuevo goto def condition_else(self): salto = self.salto.pop() -1 cuads = self.cuad[salto] cuads[3] = self.numCuad +1 self.cuad[salto] = cuads cuads = ['GOTO', -1, -1, -1] self.cuad.append(cuads) self.numCuad += 1 self.salto.push(self.numCuad) #revisa si la funcion regreso, si no crea un cuadruplo en la pila de operadores def funcion_return(self, vacio, valDireccion): if(vacio): cuads = ['RETURN',-1, -1, -1] self.numCuad += 1 self.cuad.append(cuads) return False else: cuads = ['RETURN', self.OPila.pop(), -1, valDireccion] self.numCuad += 1 self.cuad.append(cuads) return True #final del cuadruplo def function_end(self): cuads = ['ENDPROC', 1, -1, 1] self.numCuad += 1 self.cuad.append(cuads) #checa los parametros de las funciones de acuerdo al orden def function_param(self, varParametro): numParams = len(varParametro) if self.OPila.size() < numParams: print "Faltan paramentros de la funcion" sys.exit(0) lista = [] numParams = len(varParametro) -1 while numParams >= 0: for key in varParametro: if numParams == varParametro[key][1]: cuads = ['PARAMETRO', self.OPila.pop(), -1, varParametro[key][2]] print cuads numParams -= 1 self.numCuad += 1 self.cuad.append(cuads) #cuadruplo que contiene el nombre de la funcion la cual se esta llamando def llama_funcion(self, param): cuads = ['ERA', -1, -1, param] self.numCuad += 1 self.cuad.append(cuads) self.OpPila.push('(') #se hace un go sub a la funcion de la gual se hizo el go, se hace una asignacion en caso de que se regrese un valor en una temporal def llama_funcion_final(self,param, valDire, valTempo): cuads = ['GOSUB', -1, -1, param] self.numCuad += 1 self.cuad.append(cuads) cuads = ['101', valDire, -1, valTempo] self.OPila.push(valTempo) self.numCuad += 1 self.cuad.append(cuads) self.OpPila.pop() #crea una copia del numero que representa las veces que el bloque fue creado, y almacena el valor en la pila def rep(self): aux = self.get_temporal('-', self.TPila.peek(), self.TPila.pop()) valT = aux[0] cuads = [101, self.OPila.pop(), -1, valT] self.numCuad += 1 self.cuad.append(cuads) self.salto.push(self.numCuad) self.OPila.push(valT) self.TPila.push(aux[1]) #para los arreglos, crea un cuad que checa que el valor ente en el rango def dim(self, tamDim, vapunta): cuads = ['DIM', tamDim, vapunta, -1] self.numCuad += 1 self.cuad.append(cuads) self.numCuad += 1 aux = self.get_temporal('$', 'dir', -1) valT = aux[0] cuads = ['DIR', self.OPila.pop(), vapunta, valT] self.cuad.append(cuads) self.OPila.push(valT) #para las matrices, pointer representa las filas def dmT(self, tamDim, vapunta): aux = self.get_temporal('+', 'entero', 'entero') valT = aux[0] cuads = ['*', vapunta, '40002', valT] self.cuad.append(cuads) vapunta = valT cuads = ['DIM', tamDim, vapunta, -1] self.cuad.append(cuads) aux = self.get_temporal('$', 'dir', -1) valT = aux[0] saleRes = self.OPila.pop() cuads = ['DIR', saleRes, vapunta, valT] uno = valT self.cuad.append(cuads) aux = self.get_temporal('+', 'entero', 'entero') valT = aux[0] cuads = ['+', vapunta, '40000', valT] self.cuad.append(cuads) self.OPila.push(valT) aux = self.get_temporal('$', 'dir', -1) valT = aux[0] cuads = ['DIR', saleRes, self.OPila.pop(), valT] self.cuad.append(cuads) tempo = self.OPila.pop() self.OPila.push(valT) self.OPila.push(tempo) self.OPila.push(uno) self.numCuad += 4 #al inicializar una matriz, revisa la dimension, crea un apuntador para que asigne algo al siguiente valor def dmTP(self, valDire, casilla, valTam): casilla *= 2 cuads = ['DIMC', valTam, casilla, -1] self.cuad.append(cuads) aux = self.get_temporal('$', 'dir', -1) valT = aux[0] cuads = ['DIRC', valDire, (casilla+1), valT] self.cuad.append(cuads) self.asign(valT) aux = self.get_temporal('$', 'dir', -1) valT = aux[0] cuads = ['DIRC', valDire, casilla, valT] self.cuad.append(cuads) self.asign(valT) self.numCuad += 3 #checa la dimension, obtiene la direccion del puntero, cuad que genera la direccion actual def dmP(self, valDire, casilla, valTam): cuads = ['DIMC', valTam, casilla, -1] self.cuad.append(cuads) aux = self.get_temporal('$', 'dir', -1) valT = aux[0] cuads = ['DIRC', valDire, casilla, valT] self.cuad.append(cuads) self.asign(valT) self.numCuad += 2 #crea el goto al main, gurda el numero de cuadruplo en la pila de saltos def princ(self): cuads = ['GOTO', -1, -1, -1] self.cuad.append(cuads) self.salto.push(self.numCuad) self.numCuad += 1 #hace el goto al programa principal def princ_goto(self): salto = self.salto.pop() cuads = self.cuad[salto] cuads[3] = self.numCuad self.cuad[salto] = cuads #concatena los cuadruplos def append_quad(self, cuadruplo): self.numCuad += 1 self.cuad.append(cuadruplo) #usado por las funciones que solo tienen un parametro def append_quad_uno(self, unoFuncion): self.numCuad += 1 cuads = [unoFuncion, self.OPila.pop(), -1, -1] self.TPila.pop() self.cuad.append(cuads) #usado por funciones que tienen dos parametros def append_quad_dos(self, dosFuncion): self.numCuad += 1 dosParam = self.OPila.pop() self.TPila.pop() cuads = [dosFuncion, self.OPila.pop(),dosParam, -1] self.TPila.pop() self.cuad.append(cuads) #usado por funciones con tres parametros def append_quad_tres(self, tresFuncion): self.numCuad += 1 uno = self.OPila.pop() self.TPila.pop() dos = self.OPila.pop() self.TPila.pop() cuads = [tresFuncion, self.OPila.pop(), dos, uno] self.TPila.pop() self.cuad.append(cuads) #usado por la funcion del triangulo def append_quad_tri(self, triaFuncion): self.numCuad += 2 y3 = self.OPila.pop() self.TPila.pop() x3 = self.OPila.pop() self.TPila.pop() y2 = self.OPila.pop() self.TPila.pop() x2 = self.OPila.pop() self.TPila.pop() y = self.OPila.pop() self.TPila.pop() x = self.OPila.pop() self.TPila.pop() spQuad = [triaFuncion, x, y, -1] self.cuad.append(spQuad) spQuad = [x2, y2, x3, y3] self.cuad.append(spQuad) #lo utilizan las expresiones para crear cuadruplos def quad(self): self.numCuad += 1 aux = self.get_temporal(self.OpPila.peek(), self.TPila.pop(), self.TPila.pop()) valT = aux[0] operando2 = self.OPila.pop() cuads = [self.OpPila.pop(), self.OPila.pop(), operando2, valT] self.cuad.append(cuads) self.OPila.push(valT) self.TPila.push(aux[1]) #imprime info def printS(self): print self.OPila.printi() #crea un apuntador a una direccion def get_temporal_point(self): aux = self.get_temporal('$', 'dir', -1) return aux[0] def OpPila_pop(self): self.OpPila.pop() def OpPila_push(self, op): self.OpPila.push(op) def TPila_push(self, op): self.TPila.push(op) def TPila_pop(self, ): self.TPila.pop() def OPila_push(self, op): self.OPila.push(op) def OPila_pop(self): return self.OPila.pop() def OPila_peek(self): return self.OPila.peek() def DPila_push(self, op): self.DPila.push(op) def DPila_pop(self): return self.DPila.pop() def IDPila_push(self, op): self.IDPila.push(op) def IDPila_pop(self): return self.IDPila.pop() def print_cuad(self): print self.cuad def get_cuad(self): return self.cuad def setalcance(self, alcance): self.alcance = alcance def getalcance(self): return self.alcance def setFuncalcance(self, alcance): self.alcanceF.push(alcance) def delFuncalcance(self): self.alcanceF.pop() def getFuncalcance(self): return self.alcanceF.peek() def setRT(self, RT): self.RT = RT def getRT(self): return self.RT def setfuncCuad(self): self.funcCuad = self.numCuad def getfuncCuad(self): return self.funcCuad
class Sintactico(): def __init__(self, lexico): self.lexico = lexico self.complex_actual = self.lexico.siguiente_componente_lexico() self.errors = 0 self.sem = Semantico() self.pila = Pila() # print(self.complex_actual) def siguiente_componente_lexico(self): self.complex_actual = self.lexico.siguiente_componente_lexico() def compara(self, token_esperado): if self.complex_actual and token_esperado == self.complex_actual.Token: self.siguiente_componente_lexico() return True elif token_esperado <= 255: self.register_error(chr(token_esperado)) else: self.register_error(token_esperado) return False def PROGRAMA(self): if self.DEFINIR_VARIABLES(): if self.DEFINIR_FUNCIONES(): if self.PRINCIPAL(): return True else: return False else: return False else: return False def DEFINIR_VARIABLES(self): self.VARIABLES() return True def VARIABLES(self): if self.VARIABLE(): if self.VARIABLES_PRIMA(): return True else: return False else: return False def VARIABLES_PRIMA(self): if self.VARIABLE(): if self.VARIABLES_PRIMA(): return True else: return False else: return True def VARIABLE(self): if self.TIPO(): if self.IDENTIFICADORES(): self.compara(val_ascii(';')) return True else: return False else: return False def TIPO(self): actual = self.get_token_actual() if actual == valor_token('int') or actual == valor_token( 'float') or actual == valor_token( 'bool') or actual == valor_token( 'char') or actual == valor_token( 'string') or actual == valor_token('void'): tipos = list(tipoDato.keys()) for t in tipos: if actual == valor_token(t): self.lexico.TIPODATO = tipoDato[t] self.compara(actual) return True else: return False def IDENTIFICADORES(self): if self.IDENTIFICADOR(): if self.IDENTIFICADORES_PRIMA(): return True else: return False else: return False def IDENTIFICADORES_PRIMA(self): actual = self.get_token_actual() if actual == val_ascii(','): self.compara(actual) if self.IDENTIFICADOR(): if self.IDENTIFICADORES_PRIMA(): return True else: return False else: return False else: return True def IDENTIFICADOR(self): actual = self.get_token_actual() if actual == valor_token('id'): self.compara(actual) if self.ES_ARREGLO(): return True else: return False else: return False def ES_ARREGLO(self): actual = self.get_token_actual() if actual == val_ascii('['): self.compara(actual) self.compara(valor_token('num')) self.compara(val_ascii(']')) return True else: return True def DEFINIR_FUNCIONES(self): self.FUNCIONES() return True def FUNCIONES(self): if self.FUNCION(): if self.FUNCIONES_PRIMA(): return True else: return False else: return False def FUNCIONES_PRIMA(self): if self.FUNCION(): if self.FUNCIONES_PRIMA(): return True else: return False else: return True def FUNCION(self): actual = self.get_token_actual() if actual == valor_token('function'): if self.lexico.FIN_GLOBALES == -1: self.lexico.FIN_GLOBALES = len(self.lexico.tabla_simbolos) self.compara(actual) if self.TIPO(): self.lexico.SECCION = 1 #definicion de variables locales. self.lexico.INICIO_LOCALES = len(self.lexico.tabla_simbolos) self.compara(valor_token('id')) self.compara(val_ascii('(')) if self.PARAMETROS_FORMALES(): self.compara(val_ascii(')')) if self.DEFINIR_VARIABLES(): self.lexico.SECCION = 2 #cuerpo de funcion local if self.CUERPO_FUNCION(): self.lexico.SECCION = 0 return True else: return False else: return False else: return False else: return False else: return False def PARAMETROS_FORMALES(self): self.PARAMETROS() return True def PARAMETROS(self): if self.PARAMETRO(): if self.PARAMETROS_PRIMA(): return True else: return False else: return False def PARAMETROS_PRIMA(self): actual = self.get_token_actual() if actual == val_ascii(','): self.compara(actual) if self.PARAMETRO(): if self.PARAMETROS_PRIMA(): return True else: return False else: return False else: return True def PARAMETRO(self): if self.TIPO(): self.compara(valor_token('id')) return True else: return False def CUERPO_FUNCION(self): if self.BLOQUE(): return True else: return False def BLOQUE(self): actual = self.get_token_actual() if actual == val_ascii('{'): self.compara(actual) if self.ORDENES(): self.compara(val_ascii('}')) return True else: return False else: return False def ORDENES(self): if self.ORDEN(): if self.ORDENES_PRIMA(): return True else: return False else: return False def ORDENES_PRIMA(self): if self.ORDEN(): if self.ORDENES_PRIMA(): return True else: return False else: return True def ORDEN(self): if self.ASIGNACION() or self.DECISION() or self.ITERACION( ) or self.ENTRADA_SALIDA() or self.BLOQUE() or self.RETORNO(): return True else: return False def ASIGNACION(self): tac = "" if self.DESTINO(): tac = self.pila.pop().Lexema + " := " self.compara(valor_token('igu')) if self.FUENTE(): tac += self.pila.pop().Lexema self.sem.genTAC(tac) self.compara(val_ascii(';')) return True else: return False else: return False def FUENTE(self): if self.EXPRESION(): return True else: self.register_error('EXPRESION') return False def DECISION(self): actual = self.get_token_actual() if actual == valor_token('if'): self.compara(actual) self.compara(val_ascii('(')) if self.EXPRESION(): self.compara(val_ascii(')')) self.compara(valor_token('then')) self.sem.genTAC("CMP " + self.pila.pop()) label_else = self.sem.genLabel() self.sem.genTAC("JNZ " + label_else) if self.ORDEN(): label_end = self.sem.genLabel() self.sem.genTAC("JMP " + label_end) self.sem.genTAC(label_else + ":") if self.TIENE_ELSE(): self.sem.genTAC(label_end + ":") return True else: return False else: return False else: self.register_error('EXPRESION') return False else: return False def TIENE_ELSE(self): actual = self.get_token_actual() if actual == valor_token('else'): self.compara(actual) if self.ORDEN(): return True else: return False else: return True def ITERACION(self): actual = self.get_token_actual() if actual == valor_token('for'): self.compara(actual) tac = "" label_inicio = self.sem.genLabel() label_fin = self.sem.genLabel() variable = self.complex_actual self.compara(valor_token('id')) self.compara(valor_token('igu')) num_inicio = self.complex_actual self.compara(valor_token('num')) self.compara(valor_token('to')) num_final = self.complex_actual self.compara(valor_token('num')) tac = variable.Lexema + " := " + num_inicio.Lexema self.sem.genTAC(tac) self.sem.genTAC(label_inicio + ": ") tmp = Simbolo(self.sem.genTemp(), Simbolo.TOKENS['ID']) self.sem.genTAC(tmp.Lexema + " := " + variable.Lexema + " < " + num_final.Lexema) self.sem.genTAC("CMP " + tmp.Lexema) self.sem.genTAC("JNZ " + label_fin) if self.ORDEN(): self.sem.genTAC(variable.Lexema + " := " + variable.Lexema + " + 1") self.sem.genTAC("JMP " + label_inicio) self.sem.genTAC(label_fin + ":") return True else: return False elif actual == valor_token('while'): self.compara(actual) self.compara(val_ascii('(')) if self.EXPRESION_LOGICA(): self.compara(val_ascii(')')) self.compara(valor_token('do')) if self.ORDEN(): return True else: return False else: return False elif actual == valor_token('do'): self.compara(actual) if self.ORDEN(): self.compara(valor_token('while')) self.compara(val_ascii('(')) if self.EXPRESION_LOGICA(): self.compara(val_ascii(')')) return True else: return False else: return False else: return False def ENTRADA_SALIDA(self): actual = self.get_token_actual() if actual == valor_token('read'): self.compara(actual) self.compara(val_ascii('(')) if self.DESTINO(): self.compara(val_ascii(')')) self.compara(val_ascii(';')) return True else: return False elif actual == valor_token('write'): self.compara(actual) self.compara(val_ascii('(')) if self.EXPRESION(): self.compara(val_ascii(')')) self.compara(val_ascii(';')) return True else: self.register_error('EXPRESION') return False else: return False def RETORNO(self): actual = self.get_token_actual() if actual == valor_token('return'): self.compara(actual) if self.EXPRESION(): self.compara(val_ascii(';')) return True else: self.register_error('EXPRESION') return False else: return False def PRINCIPAL(self): actual = self.get_token_actual() if actual == valor_token('main'): if self.lexico.FIN_GLOBALES == -1: self.lexico.FIN_GLOBALES = len(self.lexico.tabla_simbolos) self.lexico.SECCION = 3 #Cuerpo principal self.compara(actual) self.compara(val_ascii('(')) if self.PARAMETROS_FORMALES(): self.compara(val_ascii(')')) if self.BLOQUE(): return True else: return False else: return False else: return False def EXPRESION(self): actual = self.get_token_actual() if actual == val_ascii('('): self.compara(actual) if self.EXPRESION(): self.compara(val_ascii(')')) return True else: return False elif self.EXPRESION_LOGICA(): return True else: return False def EXPRESION_LOGICA(self): if self.TERMINO_LOGICO(): if self.EXPRESION_LOGICA_aux(): return True else: return False else: return False def EXPRESION_LOGICA_aux(self): tmp = "" tac = "" actual = self.get_token_actual() if actual == val_ascii('&') or actual == val_ascii('|'): operador = self.complex_actual.Lexema self.compara(actual) tmp = self.sem.genTemp() tac = tmp + " := " + self.pila.pop() + " " + operador + " " if self.TERMINO_LOGICO(): tac += self.pila.pop() self.sem.genTAC(tac) self.pila.push(tmp) if self.EXPRESION_LOGICA_aux(): return True else: return False else: return False else: return True #######Check def TERMINO_LOGICO(self): actual = self.get_token_actual() if actual == val_ascii('!'): self.compara(actual) actual = self.get_token_actual() if actual == val_ascii('('): self.compara(actual) if self.EXPRESION_LOGICA(): self.compara(val_ascii(')')) return True elif self.EXPRESION_RELACIONAL(): self.compara(val_ascii(')')) return True else: return False else: return False elif self.EXPRESION_RELACIONAL(): return True else: return False ## def TERMINO_LOGICO(self): ## actual = self.get_token_actual() ## if actual == val_ascii('!'): ## self.compara(actual) ## self.compara(val_ascii('(')) ## if self.EXPRESION_LOGICA() or self.EXPRESION_RELACIONAL(): ## self.compara(val_ascii(')')) ## return True ## else: ## return False ## elif self.EXPRESION_RELACIONAL(): ## return True ## else: ## return False def EXPRESION_RELACIONAL(self): if self.EXPRESION_ARITMETICA(): if self.EXPRESION_RELACIONAL_aux(): return True else: return False else: return False def EXPRESION_RELACIONAL_aux(self): tmp = "" tac = "" actual = self.get_token_actual() if actual == valor_token('MAY') or actual == valor_token( 'MAI') or actual == valor_token( 'IGU') or actual == valor_token( 'DIF') or actual == valor_token( 'MEN') or actual == valor_token('MEI'): operador = self.complex_actual.Lexema self.compara(actual) tmp = Simbolo(self.sem.genTemp(), Simbolo.TOKENS['ID']) operando1 = self.pila.pop() tac = tmp.Lexema + " := " + operando1.Lexema + " " + operador + " " if self.EXPRESION_ARITMETICA(): operando2 = self.pila.pop() tac += operando2.Lexema self.sem.genTAC(tac) self.pila.push(tmp) if self.EXPRESION_RELACIONAL_aux(): return True else: return False else: return False else: return True def EXPRESION_ARITMETICA(self): if self.TERMINO_ARITMETICO(): if self.EXPRESION_ARITMETICA_aux(): return True else: return False else: return False def EXPRESION_ARITMETICA_aux(self): tmp = "" tac = "" actual = self.get_token_actual() if actual == val_ascii('+') or actual == val_ascii('-'): operador = self.complex_actual.Lexema self.compara(actual) tmp = Simbolo(self.sem.genTemp(), Simbolo.TOKENS['ID']) operando1 = self.pila.pop() tac = tmp.Lexema + " := " + operando1.Lexema + " " + operador + " " if self.TERMINO_ARITMETICO(): operando2 = self.pila.pop() tac += operando2.Lexema tmp.TipoDato = self.sem.verificar(operador, operando1.TipoDato, operando2.TipoDato) if tmp.TipoDato == tipoDato["na"]: self.register_error_tipo( "No es posible aplicar el operador '{}' entre operandos de tipo '{}' y '{}'" .format(operador, tipoDatoText[operando1.TipoDato], tipoDatoText[operando2.TipoDato])) self.sem.genTAC(tac) self.pila.push(tmp) if self.EXPRESION_ARITMETICA_aux(): return True else: return False else: return False else: return True def TERMINO_ARITMETICO(self): if self.FACTOR_ARITMETICO(): if self.TERMINO_ARITMETICO_aux(): return True else: return False else: return False def TERMINO_ARITMETICO_aux(self): tac = "" tmp = "" actual = self.get_token_actual() if actual == val_ascii('*') or actual == val_ascii( '/') or actual == val_ascii('%') or actual == val_ascii('\\'): operador = self.complex_actual.Lexema self.compara(actual) tmp = self.sem.genTemp() tac = tmp + " := " + self.pila.pop() + " " + operador + " " if self.FACTOR_ARITMETICO(): tac += self.pila.pop() self.sem.genTAC(tac) self.pila.push(tmp) if self.TERMINO_ARITMETICO_aux(): return True else: return False else: return False else: return True def FACTOR_ARITMETICO(self): actual = self.get_token_actual() if actual == val_ascii('('): self.compara(actual) if self.EXPRESION_ARITMETICA(): self.compara(val_ascii(')')) return True else: return False elif self.OPERANDO(): return True else: return False def OPERANDO(self): actual = self.get_token_actual() if actual == valor_token('num') or actual == valor_token( 'numf') or actual == valor_token( 'const_string') or actual == valor_token( 'const_char') or actual == valor_token( 'true') or actual == valor_token('false'): self.pila.push(self.complex_actual) self.compara(actual) return True elif actual == val_ascii('('): self.compara(actual) if self.EXPRESION_ARITMETICA(): self.compara(val_ascii(')')) return True else: return False elif self.DESTINO(): return True elif self.INVOCAR_FUNCION(): return True else: return False def INVOCAR_FUNCION(self): actual = self.get_token_actual() if actual == valor_token('call'): self.compara(actual) self.compara(valor_token('id')) self.compara(valor_token('(')) if self.ACTUALES(): self.compara(val_ascii(')')) return True else: return False else: return False def ACTUALES(self): if self.ACTUAL(): if self.ACTUALES_aux(): return True else: return False else: return False def ACTUALES_aux(self): actual = self.get_token_actual() if actual == val_ascii(','): self.compara(actual) if self.ACTUAL(): if self.ACTUALES_aux(): return True else: return False else: return False else: return True def ACTUAL(self): if self.EXPRESION(): return True else: return False def DESTINO(self): actual = self.get_token_actual() if actual == valor_token('id'): self.pila.push(self.complex_actual) self.compara(actual) if self.ELEMENTO_ARREGLO(): return True else: return False else: return False def ELEMENTO_ARREGLO(self): actual = self.get_token_actual() if actual == val_ascii('['): self.compara(actual) if self.EXPRESION(): self.compara(val_ascii(']')) return True else: self.register_error('EXPRESION') return False else: return True def get_token_actual(self): if self.complex_actual: return self.complex_actual.Token else: return None def register_error(self, item): self.errors += 1 if type(item) == str: print("Ln: {}, se esperaba un(a): '{}'".format( self.lexico.Num_linea(), item)) elif type(item) == int: print("Ln: {}, se esperaba token# {}".format( self.lexico.Num_linea(), item)) def register_error_tipo(self, msg): self.errors += 1 print("Ln: {}, {}".format(self.lexico.Num_linea(), msg)) def TAC(self): return self.sem.code
from pila import Pila from os import system system("clear") pila = Pila() pila.push(23) pila.push(51) pila.push(45) pila.push(90) pila.push(100) pila.push(100) pila.push(100) pila.push(100) pila.pop() pila.show() print("*" * 25) print("Size: %d" % (pila.Size())) print("Estado: %d" % (pila.empty())) print("Top: %d" % (pila.Top()))
class AdminMemoria: def __init__(self): self.constante_entero = [] self.constante_flotante = [] self.constante_str = [] self.apuntador = Pila() self.globales = Memoria() self.main = Memoria() self.alcanceActual = 0 self.funciones = dict() def constTamano(self, sizeE, sizeF, sizeS): #modifica la memoria necesaria por las constantes self.constante_entero = [0] * sizeE self.constante_flotante = [0.0] * sizeF self.constante_str = [0] * sizeS def setMemoriaPrinc(self, strP, enteroP, floatP, boolP, enteroPT, floatPT, pointerP): #modifica la memoria del main self.main.setMemoria(int(strP), int(enteroP), int(floatP), int(boolP), int(enteroPT), int(floatPT), int(pointerP)) def setMemoriaGlobales(self, strP, enteroP, floatP, boolP, enteroPT, floatPT, pointerP): #modifica la memoria de las globales self.globales.setMemoria(int(strP), int(enteroP), int(floatP), int(boolP), int(enteroPT), int(floatPT), int(pointerP)) def setFunciones(self, strP, enteroP, floatP, boolP, enteroPT, floatPT, pointerP): #crea memoria para la nueva funcion, modifica la memoria y la agrega al diccionario de funciones funcion = Memoria() funcion.setMemoria(int(strP), int(enteroP), int(floatP), int(boolP), int(enteroPT), int(floatPT), int(pointerP)) self.funciones[self.alcanceActual + 1] = funcion def cambiaAlcance(self): #cambia el alcance actual al siguiente self.alcanceActual += 1 def borrar_funcion(self): #destruye la memoria asignada para la funcion y regresa al alcance anterior self.funciones[self.alcanceActual].dejarMemoria() del self.funciones[self.alcanceActual] self.alcanceActual -= 1 def escribeValor(self, dirV, valor): #escribe el valor de la direccion dada, si la direccion es un apuntador primero recupera la direccion real if dirV[1] == '7': dirV = int(dirV) if ((dirV - 10000) < 10000): #valores globales dirV = self.globales.leerValor(dirV - 10000) elif ((dirV - 20000) < 10000): #valores del main dirV = self.main.leerValor(dirV - 20000) elif ((dirV - 30000) < 10000): #valores de funciones dirV = self.funciones[self.alcanceActual].leerValor(dirV - 30000) dirV = str(dirV) dirV = int(dirV) #imprime la direccion, dirV if ((dirV - 10000) < 10000): #valores globales dirV = dirV - 10000 self.globales.escribeValor(dirV, valor) return if ((dirV - 20000) < 10000): #valores del main dirV = dirV - 20000 self.main.escribeValor(dirV, valor) return if ((dirV - 30000) < 10000): #valores de funciones dirV = dirV - 30000 self.funciones[self.alcanceActual].escribeValor(dirV, valor) return if ((dirV - 40000) < 10000): #constantes dirV = dirV - 40000 if (dirV < 1000): self.constante_entero[dirV] = int(valor) elif (dirV < 2000): self.constante_flotante[dirV - 1000] = float(valor) else: self.constante_str[dirV - 2000] = str(valor) return def escribeValorS(self, dirV, valor): #escribe valores que solo son usados como por patamentros if dirV[1] == '7': dirV = int(dirV) if ((dirV - 10000) < 10000): #valores globales dirV = self.globales.leerValor(dirV - 10000) elif ((dirV - 20000) < 10000): #valores del main dirV = self.main.leerValor(dirV - 20000) elif ((dirV - 30000) < 10000): #valores de funciones dirV = self.funciones[self.alcanceActual + 1].leerValor(dirV - 30000) dirV = str(dirV) dirV = int(dirV) #imprime la direccion, dirV if ((dirV - 10000) < 10000): #valores globales dirV = dirV - 10000 self.globales.escribeValor(dirV, valor) return if ((dirV - 20000) < 10000): #valores del main dirV = dirV - 20000 self.main.escribeValor(dirV, valor) return if ((dirV - 30000) < 10000): #valores de funciones dirV = dirV - 30000 self.funciones[self.alcanceActual + 1].escribeValor(dirV, valor) return def getValor(self, dirV): #recupera el valor de la direccion dada, en caso de que sea un apuntador primero obtiene la direccion real if dirV[1] == '7': # si la diereccion es un apuntador se recuperar la direccion actual dirV = int(dirV) if ((dirV - 10000) < 10000): #valores globales dirV = self.globales.leerValor(dirV - 10000) elif ((dirV - 20000) < 10000): #valores del main dirV = self.main.leerValor(dirV - 20000) elif ((dirV - 30000) < 10000): #valores de funciones dirV = self.funciones[self.alcanceActual].leerValor(dirV - 30000) dirV = str(dirV) dirV = int(dirV) #imprime la direccion, dirV if ((dirV - 10000) < 10000): #valores globales dirV = dirV - 10000 return self.globales.leerValor(dirV) if ((dirV - 20000) < 10000): #valores del main dirV = dirV - 20000 return self.main.leerValor(dirV) if ((dirV - 30000) < 10000): #valores de funciones dirV = dirV - 30000 return self.funciones[self.alcanceActual].leerValor(dirV) if ((dirV - 40000) < 10000): #constantes dirV = dirV - 40000 if (dirV < 1000): return int(self.constante_entero[dirV]) elif (dirV < 2000): return float(self.constante_flotante[dirV - 1000]) else: return str(self.constante_str[dirV - 2000]) def escribeValorApuntado(self, dirV, valor, alcance): #para almacenar el valor en un apuntador dirV = int(dirV) if ((dirV - 10000) < 10000): #valores globales dirV = dirV - 10000 self.globales.escribeValor(dirV, valor) return if ((dirV - 20000) < 10000): #valores del main dirV = dirV - 20000 self.main.escribeValor(dirV, valor) return if ((dirV - 30000) < 10000): #valores de funciones dirV = dirV - 30000 self.funciones[self.alcanceActual + alcance].escribeValor( dirV, valor) return def getValorApuntado(self, dirV): #para leer el valor de un apuntador dirV = int(dirV) if ((dirV - 10000) < 10000): #valores globales dirV = dirV - 10000 return self.globales.leerValor(dirV) if ((dirV - 20000) < 10000): #valores del main dirV = dirV - 20000 return self.main.leerValor(dirV) if ((dirV - 30000) < 10000): #valores de funciones dirV = dirV - 30000 return self.funciones[self.alcanceActual].leerValor(dirV) def imprimeFunciones(self): print self.alcanceActual def imprimePrinc(self): self.main.imprimeInfo() def imprimeGlobales(self): self.globales.imprimeInfo() def imprimeConstantes(self): print self.constante_entero, " ", self.constante_flotante def push_apuntador(self, valor): self.apuntador.push(valor) def pop_apuntador(self): return self.apuntador.pop()
class avail: cubo_semantico = None def __init__(self): self.temp_booleano = 4000 self.temp_entero = 5000 self.temp_flotante = 6000 self.temp_dir = 7000 self.Bloque = 0 self.OPila = Pila() self.TPila = Pila() self.OpPila = Pila() self.salto = Pila() self.numCuad = 0 self.funcCuad = 0 self.cuad = [] self.DPila = Pila() self.IDPila = Pila() self.alcanceF = Pila() self.alcance = '' self.RT = '' self.cubo_semantico = { '=': { 'entero': { 'entero': 'entero', 'flotante': 'flotante' }, 'flotante': { 'entero': 'error', 'flotante': 'flotante' } }, '>': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '<': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '>=': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '<=': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '!=': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '==': { 'entero': { 'entero': 'bool', 'flotante': 'bool' }, 'flotante': { 'entero': 'bool', 'flotante': 'bool' } }, '+': { 'entero': { 'entero': 'entero', 'flotante': 'flotante' }, 'flotante': { 'entero': 'flotante', 'flotante': 'flotante' } }, '-': { 'entero': { 'entero': 'entero', 'flotante': 'flotante' }, 'flotante': { 'entero': 'flotante', 'flotante': 'flotante' } }, '*': { 'entero': { 'entero': 'entero', 'flotante': 'flotante' }, 'flotante': { 'entero': 'flotante', 'flotante': 'flotante' } }, '/': { 'entero': { 'entero': 'entero', 'flotante': 'flotante' }, 'flotante': { 'entero': 'flotante', 'flotante': 'flotante' } }, '$': { 'dir': { '-1': 'dir' } } } #regresa el tipo de la operacion def get_tipo(self, argOper, uno, dos): esperado = self.cubo_semantico.get(argOper) if esperado != None: esperado = esperado.get(uno) if esperado != None: esperado = esperado.get(dos) return esperado print 'error' #se crea un nuevo valor temporal en base al resultado del cubo semantico def get_temporal(self, argOper, uno, dos): tempoTipo = self.get_tipo(argOper, uno, dos) if tempoTipo == 'entero': res = self.temp_entero self.temp_entero += 1 elif tempoTipo == 'flotante': res = self.temp_flotante self.temp_flotante += 1 elif tempoTipo == 'bool': res = self.temp_booleano self.temp_booleano += 1 elif uno == 'dir': res = self.temp_dir self.temp_dir += 1 res += (self.Bloque * 10000) return [res, self.get_tipo(argOper, uno, dos)] #regresa el bloque actual def getBloque(self): return self.Bloque #resetea la memoria para el siguiente bloque def setBloque(self, Bloque): self.Bloque = Bloque self.temp_booleano = 4000 self.temp_entero = 5000 self.temp_flotante = 6000 self.temp_dir = 7000 #regresa la memoria necesaria para las temporales def get_temporal_dirs(self): return [(self.temp_booleano - 4000), (self.temp_entero - 5000), (self.temp_flotante - 6000), (self.temp_dir - 7000)] #si hay una expresion para resolver def expresion(self): if (self.OpPila.size() > 0): if (self.OpPila.peek() == '>' or self.OpPila.peek() == '<' or self.OpPila.peek() == '!=' or self.OpPila.peek() == '==' or self.OpPila.peek() == '<=' or self.OpPila.peek() == '>='): self.quad() #si hay una operacion se suma o resta def sum_res(self): if (self.OpPila.size() > 0): if (self.OpPila.peek() == '+' or self.OpPila.peek() == '-'): self.quad() #si hay una operacion de multiplicacion o division def mult_div(self): if (self.OpPila.size() > 0): if (self.OpPila.peek() == '*' or self.OpPila.peek() == '/'): self.quad() #crea una asignacion def asign(self, dato): if (self.OPila.size() > 0): self.numCuad += 1 cuads = [101, self.OPila.pop(), -1, dato] self.cuad.append(cuads) #saca uno de los valores de la temporal def rep_salto(self, primDir, dirInic): valT = self.OPila.pop() cuads = ['-', valT, primDir, valT] self.numCuad += 1 self.cuad.append(cuads) salto = self.salto.pop() aux = self.get_temporal('==', self.TPila.pop(), 'entero') cuads = ['==', valT, dirInic, aux[0]] self.numCuad += 1 self.cuad.append(cuads) cuads = ['GOTOF', aux[0], -1, salto] self.numCuad += 1 self.cuad.append(cuads) #al inicio de una condicion se crea un gotof y se almacena el num de cuadruplo en la pila de saltos def condicion(self): estCondic = self.OPila.pop() tipoCondicion = self.TPila.pop() if (tipoCondicion != "bool"): print "Error, el tipo no coincide" sys.error(0) else: cuads = ['GOTOF', estCondic, -1, -1] self.cuad.append(cuads) self.numCuad += 1 self.salto.push(self.numCuad) #al final de una condicion llena el ultimo goto que fue creado con el cuadruplo actual def condicion_inicio(self): if (self.salto.size() > 0): salto = self.salto.pop() - 1 cuads = self.cuad[salto] cuads[3] = self.numCuad self.cuad[salto] = cuads #si hay un else, se debe llenar el goto del if y crear un nuevo goto def condition_else(self): salto = self.salto.pop() - 1 cuads = self.cuad[salto] cuads[3] = self.numCuad + 1 self.cuad[salto] = cuads cuads = ['GOTO', -1, -1, -1] self.cuad.append(cuads) self.numCuad += 1 self.salto.push(self.numCuad) #revisa si la funcion regreso, si no crea un cuadruplo en la pila de operadores def funcion_return(self, vacio, valDireccion): if (vacio): cuads = ['RETURN', -1, -1, -1] self.numCuad += 1 self.cuad.append(cuads) return False else: cuads = ['RETURN', self.OPila.pop(), -1, valDireccion] self.numCuad += 1 self.cuad.append(cuads) return True #final del cuadruplo def function_end(self): cuads = ['ENDPROC', 1, -1, 1] self.numCuad += 1 self.cuad.append(cuads) #checa los parametros de las funciones de acuerdo al orden def function_param(self, varParametro): numParams = len(varParametro) if self.OPila.size() < numParams: print "Faltan paramentros de la funcion" sys.exit(0) lista = [] numParams = len(varParametro) - 1 while numParams >= 0: for key in varParametro: if numParams == varParametro[key][1]: cuads = [ 'PARAMETRO', self.OPila.pop(), -1, varParametro[key][2] ] print cuads numParams -= 1 self.numCuad += 1 self.cuad.append(cuads) #cuadruplo que contiene el nombre de la funcion la cual se esta llamando def llama_funcion(self, param): cuads = ['ERA', -1, -1, param] self.numCuad += 1 self.cuad.append(cuads) self.OpPila.push('(') #se hace un go sub a la funcion de la gual se hizo el go, se hace una asignacion en caso de que se regrese un valor en una temporal def llama_funcion_final(self, param, valDire, valTempo): cuads = ['GOSUB', -1, -1, param] self.numCuad += 1 self.cuad.append(cuads) cuads = ['101', valDire, -1, valTempo] self.OPila.push(valTempo) self.numCuad += 1 self.cuad.append(cuads) self.OpPila.pop() #crea una copia del numero que representa las veces que el bloque fue creado, y almacena el valor en la pila def rep(self): aux = self.get_temporal('-', self.TPila.peek(), self.TPila.pop()) valT = aux[0] cuads = [101, self.OPila.pop(), -1, valT] self.numCuad += 1 self.cuad.append(cuads) self.salto.push(self.numCuad) self.OPila.push(valT) self.TPila.push(aux[1]) #para los arreglos, crea un cuad que checa que el valor ente en el rango def dim(self, tamDim, vapunta): cuads = ['DIM', tamDim, vapunta, -1] self.numCuad += 1 self.cuad.append(cuads) self.numCuad += 1 aux = self.get_temporal('$', 'dir', -1) valT = aux[0] cuads = ['DIR', self.OPila.pop(), vapunta, valT] self.cuad.append(cuads) self.OPila.push(valT) #para las matrices, pointer representa las filas def dmT(self, tamDim, vapunta): aux = self.get_temporal('+', 'entero', 'entero') valT = aux[0] cuads = ['*', vapunta, '40002', valT] self.cuad.append(cuads) vapunta = valT cuads = ['DIM', tamDim, vapunta, -1] self.cuad.append(cuads) aux = self.get_temporal('$', 'dir', -1) valT = aux[0] saleRes = self.OPila.pop() cuads = ['DIR', saleRes, vapunta, valT] uno = valT self.cuad.append(cuads) aux = self.get_temporal('+', 'entero', 'entero') valT = aux[0] cuads = ['+', vapunta, '40000', valT] self.cuad.append(cuads) self.OPila.push(valT) aux = self.get_temporal('$', 'dir', -1) valT = aux[0] cuads = ['DIR', saleRes, self.OPila.pop(), valT] self.cuad.append(cuads) tempo = self.OPila.pop() self.OPila.push(valT) self.OPila.push(tempo) self.OPila.push(uno) self.numCuad += 4 #al inicializar una matriz, revisa la dimension, crea un apuntador para que asigne algo al siguiente valor def dmTP(self, valDire, casilla, valTam): casilla *= 2 cuads = ['DIMC', valTam, casilla, -1] self.cuad.append(cuads) aux = self.get_temporal('$', 'dir', -1) valT = aux[0] cuads = ['DIRC', valDire, (casilla + 1), valT] self.cuad.append(cuads) self.asign(valT) aux = self.get_temporal('$', 'dir', -1) valT = aux[0] cuads = ['DIRC', valDire, casilla, valT] self.cuad.append(cuads) self.asign(valT) self.numCuad += 3 #checa la dimension, obtiene la direccion del puntero, cuad que genera la direccion actual def dmP(self, valDire, casilla, valTam): cuads = ['DIMC', valTam, casilla, -1] self.cuad.append(cuads) aux = self.get_temporal('$', 'dir', -1) valT = aux[0] cuads = ['DIRC', valDire, casilla, valT] self.cuad.append(cuads) self.asign(valT) self.numCuad += 2 #crea el goto al main, gurda el numero de cuadruplo en la pila de saltos def princ(self): cuads = ['GOTO', -1, -1, -1] self.cuad.append(cuads) self.salto.push(self.numCuad) self.numCuad += 1 #hace el goto al programa principal def princ_goto(self): salto = self.salto.pop() cuads = self.cuad[salto] cuads[3] = self.numCuad self.cuad[salto] = cuads #concatena los cuadruplos def append_quad(self, cuadruplo): self.numCuad += 1 self.cuad.append(cuadruplo) #usado por las funciones que solo tienen un parametro def append_quad_uno(self, unoFuncion): self.numCuad += 1 cuads = [unoFuncion, self.OPila.pop(), -1, -1] self.TPila.pop() self.cuad.append(cuads) #usado por funciones que tienen dos parametros def append_quad_dos(self, dosFuncion): self.numCuad += 1 dosParam = self.OPila.pop() self.TPila.pop() cuads = [dosFuncion, self.OPila.pop(), dosParam, -1] self.TPila.pop() self.cuad.append(cuads) #usado por funciones con tres parametros def append_quad_tres(self, tresFuncion): self.numCuad += 1 uno = self.OPila.pop() self.TPila.pop() dos = self.OPila.pop() self.TPila.pop() cuads = [tresFuncion, self.OPila.pop(), dos, uno] self.TPila.pop() self.cuad.append(cuads) #usado por la funcion del triangulo def append_quad_tri(self, triaFuncion): self.numCuad += 2 y3 = self.OPila.pop() self.TPila.pop() x3 = self.OPila.pop() self.TPila.pop() y2 = self.OPila.pop() self.TPila.pop() x2 = self.OPila.pop() self.TPila.pop() y = self.OPila.pop() self.TPila.pop() x = self.OPila.pop() self.TPila.pop() spQuad = [triaFuncion, x, y, -1] self.cuad.append(spQuad) spQuad = [x2, y2, x3, y3] self.cuad.append(spQuad) #lo utilizan las expresiones para crear cuadruplos def quad(self): self.numCuad += 1 aux = self.get_temporal(self.OpPila.peek(), self.TPila.pop(), self.TPila.pop()) valT = aux[0] operando2 = self.OPila.pop() cuads = [self.OpPila.pop(), self.OPila.pop(), operando2, valT] self.cuad.append(cuads) self.OPila.push(valT) self.TPila.push(aux[1]) #imprime info def printS(self): print self.OPila.printi() #crea un apuntador a una direccion def get_temporal_point(self): aux = self.get_temporal('$', 'dir', -1) return aux[0] def OpPila_pop(self): self.OpPila.pop() def OpPila_push(self, op): self.OpPila.push(op) def TPila_push(self, op): self.TPila.push(op) def TPila_pop(self, ): self.TPila.pop() def OPila_push(self, op): self.OPila.push(op) def OPila_pop(self): return self.OPila.pop() def OPila_peek(self): return self.OPila.peek() def DPila_push(self, op): self.DPila.push(op) def DPila_pop(self): return self.DPila.pop() def IDPila_push(self, op): self.IDPila.push(op) def IDPila_pop(self): return self.IDPila.pop() def print_cuad(self): print self.cuad def get_cuad(self): return self.cuad def setalcance(self, alcance): self.alcance = alcance def getalcance(self): return self.alcance def setFuncalcance(self, alcance): self.alcanceF.push(alcance) def delFuncalcance(self): self.alcanceF.pop() def getFuncalcance(self): return self.alcanceF.peek() def setRT(self, RT): self.RT = RT def getRT(self): return self.RT def setfuncCuad(self): self.funcCuad = self.numCuad def getfuncCuad(self): return self.funcCuad
class AdminMemoria: def __init__(self): self.constante_entero = [] self.constante_flotante = [] self.constante_str = [] self.apuntador = Pila() self.globales = Memoria() self.main = Memoria() self.alcanceActual = 0 self.funciones = dict() def constTamano(self, sizeE, sizeF, sizeS): #modifica la memoria necesaria por las constantes self.constante_entero = [0] * sizeE self.constante_flotante = [0.0] * sizeF self.constante_str = [0] * sizeS def setMemoriaPrinc(self, strP, enteroP, floatP, boolP, enteroPT, floatPT, pointerP): #modifica la memoria del main self.main.setMemoria(int(strP), int(enteroP), int(floatP), int(boolP), int(enteroPT), int(floatPT), int(pointerP)) def setMemoriaGlobales(self, strP, enteroP, floatP, boolP, enteroPT, floatPT, pointerP): #modifica la memoria de las globales self.globales.setMemoria(int(strP), int(enteroP), int(floatP), int(boolP), int(enteroPT), int(floatPT), int(pointerP)) def setFunciones(self, strP, enteroP, floatP, boolP, enteroPT, floatPT, pointerP): #crea memoria para la nueva funcion, modifica la memoria y la agrega al diccionario de funciones funcion = Memoria() funcion.setMemoria(int(strP), int(enteroP), int(floatP), int(boolP), int(enteroPT), int(floatPT), int(pointerP)) self.funciones[self.alcanceActual+1] = funcion def cambiaAlcance(self): #cambia el alcance actual al siguiente self.alcanceActual += 1 def borrar_funcion(self): #destruye la memoria asignada para la funcion y regresa al alcance anterior self.funciones[self.alcanceActual].dejarMemoria() del self.funciones[self.alcanceActual] self.alcanceActual -= 1 def escribeValor(self, dirV, valor): #escribe el valor de la direccion dada, si la direccion es un apuntador primero recupera la direccion real if dirV[1] == '7': dirV = int(dirV) if((dirV-10000) < 10000): #valores globales dirV = self.globales.leerValor(dirV-10000) elif((dirV-20000) < 10000): #valores del main dirV = self.main.leerValor(dirV-20000) elif((dirV-30000) < 10000): #valores de funciones dirV = self.funciones[self.alcanceActual].leerValor(dirV-30000) dirV = str(dirV) dirV = int(dirV) #imprime la direccion, dirV if((dirV-10000) < 10000): #valores globales dirV = dirV-10000 self.globales.escribeValor(dirV, valor) return if((dirV-20000) < 10000): #valores del main dirV = dirV-20000 self.main.escribeValor(dirV, valor) return if((dirV-30000) < 10000): #valores de funciones dirV = dirV-30000 self.funciones[self.alcanceActual].escribeValor(dirV, valor) return if((dirV-40000) < 10000): #constantes dirV = dirV-40000 if(dirV < 1000): self.constante_entero[dirV] = int(valor) elif(dirV < 2000): self.constante_flotante[dirV-1000] = float(valor) else: self.constante_str[dirV-2000] = str(valor) return def escribeValorS(self, dirV, valor): #escribe valores que solo son usados como por patamentros if dirV[1] == '7': dirV = int(dirV) if((dirV-10000) < 10000): #valores globales dirV = self.globales.leerValor(dirV-10000) elif((dirV-20000) < 10000): #valores del main dirV = self.main.leerValor(dirV-20000) elif((dirV-30000) < 10000): #valores de funciones dirV = self.funciones[self.alcanceActual+1].leerValor(dirV-30000) dirV = str(dirV) dirV = int(dirV) #imprime la direccion, dirV if((dirV-10000) < 10000): #valores globales dirV = dirV-10000 self.globales.escribeValor(dirV, valor) return if((dirV-20000) < 10000): #valores del main dirV = dirV-20000 self.main.escribeValor(dirV, valor) return if((dirV-30000) < 10000): #valores de funciones dirV = dirV-30000 self.funciones[self.alcanceActual+1].escribeValor(dirV, valor) return def getValor(self, dirV): #recupera el valor de la direccion dada, en caso de que sea un apuntador primero obtiene la direccion real if dirV[1] == '7': # si la diereccion es un apuntador se recuperar la direccion actual dirV = int(dirV) if((dirV-10000) < 10000): #valores globales dirV = self.globales.leerValor(dirV-10000) elif((dirV-20000) < 10000): #valores del main dirV = self.main.leerValor(dirV-20000) elif((dirV-30000) < 10000): #valores de funciones dirV = self.funciones[self.alcanceActual].leerValor(dirV-30000) dirV = str(dirV) dirV = int(dirV) #imprime la direccion, dirV if((dirV-10000) < 10000): #valores globales dirV = dirV-10000 return self.globales.leerValor(dirV) if((dirV-20000) < 10000): #valores del main dirV = dirV-20000 return self.main.leerValor(dirV) if((dirV-30000) < 10000): #valores de funciones dirV = dirV-30000 return self.funciones[self.alcanceActual].leerValor(dirV) if((dirV-40000) < 10000): #constantes dirV = dirV-40000 if(dirV < 1000): return int(self.constante_entero[dirV]) elif(dirV < 2000): return float(self.constante_flotante[dirV-1000]) else: return str(self.constante_str[dirV-2000]) def escribeValorApuntado(self, dirV, valor, alcance): #para almacenar el valor en un apuntador dirV = int(dirV) if((dirV-10000) < 10000): #valores globales dirV = dirV-10000 self.globales.escribeValor(dirV, valor) return if((dirV-20000) < 10000): #valores del main dirV = dirV-20000 self.main.escribeValor(dirV, valor) return if((dirV-30000) < 10000): #valores de funciones dirV = dirV-30000 self.funciones[self.alcanceActual+alcance].escribeValor(dirV, valor) return def getValorApuntado(self, dirV): #para leer el valor de un apuntador dirV = int(dirV) if((dirV-10000) < 10000): #valores globales dirV = dirV-10000 return self.globales.leerValor(dirV) if((dirV-20000) < 10000): #valores del main dirV = dirV-20000 return self.main.leerValor(dirV) if((dirV-30000) < 10000): #valores de funciones dirV = dirV-30000 return self.funciones[self.alcanceActual].leerValor(dirV) def imprimeFunciones(self): print self.alcanceActual def imprimePrinc(self): self.main.imprimeInfo() def imprimeGlobales(self): self.globales.imprimeInfo() def imprimeConstantes(self): print self.constante_entero, " ", self.constante_flotante def push_apuntador(self, valor): self.apuntador.push(valor) def pop_apuntador(self): return self.apuntador.pop()