예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
    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
예제 #7
0
    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
예제 #8
0
    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
예제 #9
0
    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
예제 #10
0
    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