def termino(self, lista_variables): """ Define un termino { Termino ::= ClausulaY [ "o" ClausulaY] ... } Se usan dentro de los condicionales 'si' y el bucle 'mientras' """ if self.debug: print "<termino params='%s'>"%xml_prepare(lista_variables) if self.gen_arbol: retornar_valor = {'o': [self.clausula_y(lista_variables)]} #Lista con las expresiones 'o' else: self.clausula_y(lista_variables) while self.token_actual == 'o': self.avanza_token() if self.gen_arbol: retornar_valor['o'].append(self.clausula_y(lista_variables)) else: self.clausula_y(lista_variables) if self.debug: print "</termino>" if self.gen_arbol: return retornar_valor
def expresion_general(self, lista_variables, c_funcion, c_bucle): """ Define una expresion general { Expresion | ExpresionVacia } Generalmente se trata de una expresión dentro de las etiquetas 'inicio' y 'fin' o entre 'inicia-ejecucion' y 'termina-ejecucion' """ if self.debug: print "<expresion_general params='%s'>"%xml_prepare(lista_variables) if self.gen_arbol: retornar_valor = [] #Una lista de funciones while self.token_actual != 'fin' and self.token_actual != 'termina-ejecucion': if self.gen_arbol: retornar_valor += self.expresion(lista_variables, c_funcion, c_bucle) else: self.expresion(lista_variables, c_funcion, c_bucle) if self.token_actual != ';' and self.token_actual != 'fin' and self.token_actual != 'termina-ejecucion': raise KarelException("Se esperaba ';'") elif self.token_actual == ';': self.avanza_token() elif self.token_actual == 'fin': raise KarelException("Se esperaba ';'") elif self.token_actual == 'termina-ejecucion': raise KarelException("Se esperaba ';'") if self.debug: print "</expresion_general>" if self.gen_arbol: return retornar_valor
def expresion_mientras(self, lista_variables, c_funcion): """ Define la expresion del bucle MIENTRAS { ExpresionMientras ::= "Mientras" Termino "hacer" Expresion } """ if self.debug: print "<expresion_mientras params='%s'>"%xml_prepare(lista_variables) if self.gen_arbol: retornar_valor = { 'estructura': 'mientras', 'argumento': None, 'cola': [] } self.avanza_token() if self.gen_arbol: retornar_valor['argumento'] = self.termino(lista_variables) else: self.termino(lista_variables) if self.token_actual != 'hacer': raise KarelException("Se esperaba 'hacer'") self.avanza_token() if self.gen_arbol: retornar_valor['cola'] = self.expresion(lista_variables, c_funcion, True) else: self.expresion(lista_variables, c_funcion, True) if self.debug: print "</expresion_mientras>" if self.gen_arbol: return retornar_valor
def clausula_y(self, lista_variables): """ Define una clausula conjuntiva { ClausulaY ::= ClausulaNo ["Y" ClausulaNo]... } """ if self.debug: print "<clausula_y params='%s'>"%xml_prepare(lista_variables) if self.gen_arbol: retornar_valor = {'y': [self.clausula_no(lista_variables)]} else: self.clausula_no(lista_variables) while self.token_actual == 'y': self.avanza_token() if self.gen_arbol: retornar_valor['y'].append(self.clausula_no(lista_variables)) else: self.clausula_no(lista_variables) if self.debug: print "</clausula_y>" if self.gen_arbol: return retornar_valor
def clausula_no(self, lista_variables): """ Define una clausula de negacion { ClausulaNo ::= ["NO"] ClausulaAtomica } """ if self.debug: print "<clausula_no params='%s'>"%xml_prepare(lista_variables) if self.gen_arbol: retornar_valor = None if self.token_actual == 'no': self.avanza_token() if self.gen_arbol: retornar_valor = {'no': self.clausula_atomica(lista_variables)} else: self.clausula_atomica(lista_variables) else: if self.gen_arbol: retornar_valor = self.clausula_atomica(lista_variables) else: self.clausula_atomica(lista_variables) if self.debug: print "</clausula_no>" if self.gen_arbol: return retornar_valor
def expresion_entera(self, lista_variables): """ Define una expresion numerica entera { ExpresionEntera ::= { Decimal | Identificador | "PRECEDE" "(" ExpresionEntera ")" | "SUCEDE" "(" ExpresionEntera ")" }{ } """ if self.debug: print "<expresion_entera params='%s'>"%xml_prepare(lista_variables) if self.gen_arbol: retornar_valor = None #En este punto hay que verificar que se trate de un numero entero try: #Intentamos convertir el numero if self.gen_arbol: retornar_valor = int(self.token_actual, 10) else: int(self.token_actual, 10) except ValueError: #No era un entero if self.token_actual in self.expresiones_enteras: if self.gen_arbol: retornar_valor = { self.token_actual: None } self.avanza_token() if self.token_actual == '(': self.avanza_token() if self.gen_arbol: retornar_valor[retornar_valor.keys()[0]] = self.expresion_entera(lista_variables) else: self.expresion_entera(lista_variables) if self.token_actual == ')': self.avanza_token() else: raise KarelException("Se esperaba ')'") else: raise KarelException("Se esperaba '('") elif self.token_actual not in self.palabras_reservadas and self.es_identificador_valido(self.token_actual): #Se trata de una variable definida por el usuario if self.token_actual not in lista_variables: raise KarelException("La variable '%s' no está definida en este contexto"%self.token_actual) if self.gen_arbol: retornar_valor = self.token_actual self.avanza_token() else: raise KarelException("Se esperaba un entero, variable, sucede o predece, '%s' no es válido"%self.token_actual) else: #Si se pudo convertir, avanzamos self.avanza_token() if self.debug: print "</expresion_entera>" if self.gen_arbol: return retornar_valor
def expresion_si(self, lista_variables, c_funcion, c_bucle): """ Define la expresion del condicional SI { ExpresionSi ::= "SI" Termino "ENTONCES" Expresion ["SINO" Expresion ] } """ if self.debug: print "<expresion_si params='%s'>"%xml_prepare(lista_variables) if self.gen_arbol: retornar_valor = { 'estructura': 'si', 'argumento': None, 'cola': [] } self.avanza_token() if self.gen_arbol: retornar_valor['argumento'] = self.termino(lista_variables) else: self.termino(lista_variables) if self.token_actual != 'entonces': raise KarelException("Se esperaba 'entonces'") self.avanza_token() if self.gen_arbol: retornar_valor['cola'] = self.expresion(lista_variables, c_funcion, c_bucle) else: self.expresion(lista_variables, c_funcion, c_bucle) if self.token_actual == 'sino': if self.gen_arbol: retornar_valor.update({'sino-cola': []}) self.avanza_token() if self.gen_arbol: retornar_valor['sino-cola'] = self.expresion(lista_variables, c_funcion, c_bucle) else: self.expresion(lista_variables, c_funcion, c_bucle) if self.debug: print "</expresion_si>" if self.gen_arbol: return retornar_valor
def clausula_atomica(self, lista_variables): """ Define una clausila atomica { ClausulaAtomica ::= { "SI-ES-CERO" "(" ExpresionEntera ")" | FuncionBooleana | "(" Termino ")" }{ } """ if self.debug: print "<clausula_atomica params='%s'>"%xml_prepare(lista_variables) if self.gen_arbol: retornar_valor = None if self.token_actual == 'si-es-cero': self.avanza_token() if self.token_actual == '(': self.avanza_token() if self.gen_arbol: retornar_valor = {'si-es-cero': self.expresion_entera(lista_variables)} else: self.expresion_entera(lista_variables) if self.token_actual == ')': self.avanza_token() else: raise KarelException("Se esperaba ')'") else: raise KarelException("Se esperaba '('") elif self.token_actual == '(': self.avanza_token() if self.gen_arbol: retornar_valor = self.termino(lista_variables) else: self.termino(lista_variables) if self.token_actual == ')': self.avanza_token() else: raise KarelException("Se esperaba ')'") else: if self.gen_arbol: retornar_valor = self.funcion_booleana() else: self.funcion_booleana() if self.debug: print "</clausula_atomica>" if self.gen_arbol: return retornar_valor
def expresion_repite(self, lista_variables, c_funcion): """ Define la expresion del bucle REPITE { ExpresionRepite::= "repetir" ExpresionEntera "veces" Expresion } """ if self.debug: print "<expresion_repite params='%s'>"%xml_prepare(lista_variables) if self.gen_arbol: retornar_valor = { 'estructura': 'repite', 'argumento': None, 'cola': [] } self.avanza_token() if self.gen_arbol: retornar_valor['argumento'] = self.expresion_entera(lista_variables) else: self.expresion_entera(lista_variables) if self.token_actual != 'veces': raise KarelException("Se esperaba la palabra 'veces', '%s' no es válido"%self.token_actual) self.avanza_token() if self.gen_arbol: retornar_valor['cola'] = self.expresion(lista_variables, c_funcion, True) else: self.expresion(lista_variables, c_funcion, True) if self.debug: print "</expresion_repite>" if self.gen_arbol: return retornar_valor
def expresion(self, lista_variables, c_funcion, c_bucle): """ Define una expresion { Expresion :: = { "apagate" "gira-izquierda" "avanza" "coge-zumbador" "deja-zumbador" "sal-de-instruccion" ExpresionLlamada ExpresionSi ExpresionRepite ExpresionMientras "inicio" ExpresionGeneral [";" ExpresionGeneral] ... "fin" }{ } Recibe para comprobar una lista con las variables válidas en este contexto, tambien comprueba mediante c_funcion si esta en un contexto donde es valido el sal-de-instruccion. """ if self.debug: print "<expresion params='%s'>"%xml_prepare(lista_variables) if self.gen_arbol: retornar_valor = [] if self.token_actual in self.instrucciones: if self.token_actual == 'sal-de-instruccion': if c_funcion: if self.gen_arbol: retornar_valor = [self.token_actual] self.avanza_token() else: self.avanza_token() else: raise KarelException("No es posible usar 'sal-de-instruccion' fuera de una instruccion :)") elif self.token_actual == 'sal-de-bucle': if c_bucle: if self.gen_arbol: retornar_valor = [self.token_actual] self.avanza_token() else: self.avanza_token() else: raise KarelException("No es posible usar 'sal-de-bucle' fuera de un bucle :)") else: if self.gen_arbol: retornar_valor = [self.token_actual] self.avanza_token() else: self.avanza_token() elif self.token_actual == 'si': if self.gen_arbol: retornar_valor = [self.expresion_si(lista_variables, c_funcion, c_bucle)] else: self.expresion_si(lista_variables, c_funcion, c_bucle) elif self.token_actual == 'mientras': if self.gen_arbol: retornar_valor = [self.expresion_mientras(lista_variables, c_funcion)] else: self.expresion_mientras(lista_variables, c_funcion) elif self.token_actual == 'repite' or self.token_actual == 'repetir': if self.gen_arbol: retornar_valor = [self.expresion_repite(lista_variables, c_funcion)] else: self.expresion_repite(lista_variables, c_funcion) elif self.token_actual == 'inicio': self.avanza_token() if self.gen_arbol: retornar_valor = self.expresion_general(lista_variables, c_funcion, c_bucle) else: self.expresion_general(lista_variables, c_funcion, c_bucle) if self.token_actual == 'fin': self.avanza_token() else: raise KarelException("Se esperaba 'fin' para concluir el bloque, encontré '%s'"%self.token_actual) elif self.token_actual not in self.palabras_reservadas and self.es_identificador_valido(self.token_actual): #Se trata de una instrucción creada por el usuario if self.prototipo_funciones.has_key(self.token_actual) or self.funciones.has_key(self.token_actual): nombre_funcion = self.token_actual if self.gen_arbol: retornar_valor = [{ 'estructura': 'instruccion', 'nombre': nombre_funcion, 'argumento': [] }] self.avanza_token() requiere_parametros = True num_parametros = 0 if self.token_actual == '(': self.avanza_token() while True: if self.gen_arbol: retornar_valor[0]['argumento'].append(self.expresion_entera(lista_variables)) else: self.expresion_entera(lista_variables) num_parametros += 1 if self.token_actual == ')': #self.lexer.push_token(')') #Devolvemos el token a la pila break elif self.token_actual == ',': self.avanza_token() else: raise KarelException("Se esperaba ',', encontré '%s'"%self.token_actual) if self.prototipo_funciones.has_key(nombre_funcion): if num_parametros != len(self.prototipo_funciones[nombre_funcion]): raise KarelException("Estas intentando llamar la funcion '%s' con %d parámetros, pero así no fue definida"%(nombre_funcion, num_parametros)) else: if num_parametros != len(self.funciones[nombre_funcion]): raise KarelException("Estas intentando llamar la funcion '%s' con %d parámetros, pero así no fue definida"%(nombre_funcion, num_parametros)) self.avanza_token() else: raise KarelException("La instrucción '%s' no ha sido previamente definida, pero es utilizada"%self.token_actual) else: raise KarelException("Se esperaba un procedimiento, '%s' no es válido"%self.token_actual) if self.debug: print "</expresion>" if self.gen_arbol: return retornar_valor