Пример #1
0
def compila(*args, **kwargs):
    json_data = json.loads(request.data)
    errores = ColeccionError()
    lexico = Lexico(codigo=json_data.get('codigo', ''), errores=errores)
    componentes_lexicos = []
    while True:
        componente_lexico = lexico.siguiente_componente_lexico()
        if componente_lexico:
            componentes_lexicos.append({
                "token": componente_lexico.token,
                "lexema": componente_lexico.lexema,
                "codigo": componente_lexico.codigo
            })

        else:
            break

    resultado = {'componentes_lexicos': componentes_lexicos}
    resultado['errores'] = [{
        'tipo': e.tipo,
        'num_linea': e.num_linea,
        'mensaje': e.mensaje
    } for e in lexico.errores]
    resultado['tabla_de_simbolos'] = [{
        'token': s.token,
        'lexema': s.lexema,
        'codigo': s.codigo
    } for s in lexico.tabla_de_simbolos]
    return (resultado, 200)
Пример #2
0
 def __init__(self, codigo="", errores=ColeccionError()):
     self.codigo = codigo + " "
     self.tabla_de_simbolos = []
     self.indice = -1
     self.inicio_lexema = 0
     self.numero_de_linea = 1
     self.inicio = 0
     self.estado = 0
     self.caracter = self.codigo[0]
     self.lexema = ""
     self.token = None
     self.__errores = errores
     self.errores = self.__errores.coleccion
     self.__cargar_palabras_reservadas()
Пример #3
0
 def __init__(self, codigo="", errores=ColeccionError()):
     self.codigo = codigo + " "
     self.tabla_de_simbolos = []
     self.indice = -1
     self.inicio_lexema = 0
     self.numero_de_linea = 1
     self.inicio = 0
     self.estado = 0
     self.caracter = self.codigo[0]
     self.lexema = ""
     self.token = None
     self.zona_de_codigo = Zonas.DEF_VARIABLES_GLOBALES
     self.fin_definicion_palabras_reservadas = None
     self.fin_definicion_variables_globales = None
     self.inicio_definicion_variables_locales = None
     self.fin_definicion_variables_locales = None
     self.__errores = errores
     self.errores = self.__errores.coleccion
     self.__cargar_palabras_reservadas()
Пример #4
0
 def __init__(self, codigo=''):
     self.errores = ColeccionError()
     self.lexico = Lexico(codigo=codigo, errores=self.errores)
     self.complex = self.siguiente_componente_lexico()
Пример #5
0
class Sintactico(object):
    def __init__(self, codigo=''):
        self.errores = ColeccionError()
        self.lexico = Lexico(codigo=codigo, errores=self.errores)
        self.complex = self.siguiente_componente_lexico()

    def siguiente_componente_lexico(self):
        self.complex = self.lexico.siguiente_componente_lexico()
        return self.complex

    @property
    def numero_de_linea(self):
        return self.lexico.numero_de_linea

    def __verifica(self, token):
        if isinstance(token, str) and len(token) == 1:
            token = ord(token)

        elif not isinstance(token, int):
            raise ValueError()

        # print(f'{self.complex.token} == {token}? {self.complex.token == token}')
        if self.complex is not None:
            return self.complex.token == token

        return False

    def __compara(self, token):
        if isinstance(token, str) and len(token) == 1:
            token = ord(token)

        elif not isinstance(token, int):
            raise ValueError()

        if self.complex is not None and self.complex.token == token:
            self.siguiente_componente_lexico()

        else:
            self.__agregar_error(
                tipo='SINTACTICO',
                mensaje=
                f"Se esperaba: '{chr(token) if token < 256 else TOKENS_INV[token]}'"
            )

    def __agregar_error(self, tipo='SINTACTICO', mensaje=None):
        self.errores.agregar(
            Error(tipo=tipo, num_linea=self.numero_de_linea, mensaje=mensaje))

    def PROGRAMA(self):
        if self.DEFINIR_VARIABLES():
            if self.DEFINIR_FUNCIONES():
                if self.PRINCIPAL():
                    return True

                else:
                    self.__agregar_error(
                        tipo='SINTACTICO',
                        mensaje='Se requiere cuerpo principal del programa')

        return False

    def DEFINIR_VARIABLES(self):
        self.VARIABLES()
        return True

    # VARIABLES -> VARIABLES VARIABLE | VARIABLE
    # VARIABLES -> VARIABLE VARIABLES_PRIMA
    # VARIABLES_PRIMA -> VARIABLE VARIABLES_PRIMA | ϵ

    def VARIABLES(self):
        if self.VARIABLE():
            if self.VARIABLES_PRIMA():
                return True

        return False

    def VARIABLES_PRIMA(self):
        if self.VARIABLE():
            if self.VARIABLES_PRIMA():
                return True

            return False

        return True

    def VARIABLE(self):
        if self.TIPO():
            if self.IDENTIFICADORES():
                self.__compara(';')
                return True

        return False

    def TIPO(self):
        if next((True
                 for x in ('INT', 'BOOL', 'FLOAT', 'CHAR', 'STRING', 'VOID')
                 if self.__verifica(TOKENS[x])), False):
            self.__compara(self.complex.token)
            return True

        return False

    # IDENTIFICADORES -> IDENTIFICADORES , IDENTIFICADOR | IDENTIFICADOR
    # IDENTIFICADORES -> IDENTIFICADOR IDENTIFICADORES_PRIMA
    # IDENTIFICADORES_PRIMA -> , IDENTIFICADOR IDENTIFICADORES_PRIMA | ϵ

    def IDENTIFICADORES(self):
        if self.IDENTIFICADOR():
            if self.IDENTIFICADORES_PRIMA():
                return True

        return False

    def IDENTIFICADORES_PRIMA(self):
        if self.__verifica(','):
            self.__compara(',')
            if self.IDENTIFICADOR():
                if self.IDENTIFICADORES_PRIMA():
                    return True

            return False

        return True

    def IDENTIFICADOR(self):
        if self.__verifica(TOKENS['ID']):
            self.__compara(self.complex.token)
            if self.ES_ARREGLO():
                return True

        return False

    def ES_ARREGLO(self):
        if self.__verifica('['):
            self.__compara(self.complex.token)
            self.__compara(TOKENS['NUM'])
            self.__compara(']')
            return True

        return True

    def DEFINIR_FUNCIONES(self):
        self.FUNCIONES()
        return True

    # FUNCIONES -> FUNCIONES FUNCION | FUNCION
    # FUNCIONES -> FUNCION FUNCIONES_PRIMA
    # FUNCIONES_PRIMA -> FUNCION FUNCIONES_PRIMA | ϵ

    def FUNCIONES(self):
        if self.FUNCION():
            if self.FUNCIONES_PRIMA():
                return True

        return False

    def FUNCIONES_PRIMA(self):
        if self.FUNCION():
            if self.FUNCIONES_PRIMA():
                return True

            return False

        return True

    def FUNCION(self):
        if self.__verifica(TOKENS['FUNCTION']):
            self.__compara(self.complex.token)
            if self.TIPO():
                self.__compara(TOKENS['ID'])
                self.__compara('(')
                if self.PARAMETROS_FORMALES():
                    self.__compara(')')
                    if self.DEFINIR_VARIABLES():
                        if self.CUERPO_FUNCION():
                            return True

        return False

    def PARAMETROS_FORMALES(self):
        self.PARAMETROS()
        return True

    def PARAMETROS(self):
        if self.PARAMETRO():
            if self.PARAMETROS_PRIMA():
                return True

        return False

    def PARAMETROS_PRIMA(self):
        if self.__verifica(','):
            self.__compara(',')
            if self.PARAMETRO():
                if self.PARAMETROS_PRIMA():
                    return True

            return False

        return True

    def PARAMETRO(self):
        if self.TIPO():
            self.__compara(TOKENS['ID'])
            return True

        return False

    def CUERPO_FUNCION(self):
        if self.BLOQUE():
            return True

        return False

    def BLOQUE(self):
        if self.__verifica('{'):
            self.__compara(self.complex.token)
            if self.ORDENES():
                self.__compara('}')
                return True

        return False

    # ORDENES -> ORDENES ORDEN | ORDEN
    # ORDENES -> ORDEN ORDENES_PRIMA
    # ORDENES_PRIMA -> ORDEN ORDENES_PRIMA | ϵ

    def ORDENES(self):
        if self.ORDEN():
            if self.ORDENES_PRIMA():
                return True

        return False

    def ORDENES_PRIMA(self):
        if self.ORDEN():
            if self.ORDENES_PRIMA():
                return True

            return False

        return True

    def ORDEN(self):
        if any((self.ASIGNACION(), self.DECISION(), self.ITERACION(),
                self.ENTRADA_SALIDA(), self.BLOQUE(), self.RETORNO())):
            return True

        return False

    def ASIGNACION(self):
        if self.DESTINO():
            self.__compara(TOKENS['IGU'])
            if self.FUENTE():
                self.__compara(';')
                return True

        return False

    def DESTINO(self):
        if self.__verifica(TOKENS['ID']):
            self.__compara(self.complex.token)
            if self.ELEMENTO_ARREGLO():
                return True

        return False

    def ELEMENTO_ARREGLO(self):
        if self.__verifica('['):
            self.__compara(self.complex.token)
            if self.EXPRESION():
                self.__compara(']')
                return True

            self.__agregar_error(mensaje='Se esperaba una Expresion')
            return False

        return True

    def FUENTE(self):
        if self.EXPRESION():
            return True

        self.__agregar_error(tipo='SINTACTICO',
                             mensaje='Se esperaba una expresion')
        return False

    def DECISION(self):
        if self.__verifica(TOKENS['IF']):
            self.__compara(self.complex.token)
            self.__compara('(')
            if self.EXPRESION():
                self.__compara(')')
                self.__compara(TOKENS['THEN'])
                if self.ORDEN():
                    if self.TIENE_ELSE():
                        return True

                else:
                    self.__agregar_error(tipo='SINTACTICO',
                                         mensaje='Se esperaba una orden')

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una expresion')

        return False

    def TIENE_ELSE(self):
        if self.__verifica(TOKENS['ELSE']):
            self.__compara(self.complex.token)
            if self.ORDEN():
                return True

            self.__agregar_error(tipo='SINTACTICO',
                                 mensaje='Se esperaba una orden')
            return False

        return True

    def ITERACION(self):
        if self.__verifica(TOKENS['FOR']):
            self.__compara(self.complex.token)
            self.__compara(TOKENS['ID'])
            self.__compara(TOKENS['IGU'])
            if self.EXPRESION():
                self.__compara(TOKENS['TO'])
                if self.EXPRESION():
                    if self.ORDEN():
                        return True

                    else:
                        self.__agregar_error(tipo='SINTACTICO',
                                             mensaje='Se esperaba una orden')

                else:
                    self.__agregar_error(tipo='SINTACTICO',
                                         mensaje='Se esperaba una expresion')

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una expresion')

        elif self.__verifica(TOKENS['WHILE']):
            self.__compara(self.complex.token)
            self.__compara('(')
            if self.EXPRESION_LOGICA():
                self.__compara(')')
                self.__compara(TOKENS['DO'])
                if self.ORDEN():
                    return True

                else:
                    self.__agregar_error(tipo='SINTACTICO',
                                         mensaje='Se esperaba una orden')

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una expresion')

        elif self.__verifica(TOKENS['DO']):
            if self.ORDEN():
                self.__compara(TOKENS['WHILE'])
                self.__compara('(')
                if self.EXPRESION_LOGICA():
                    self.__compara(')')
                    return True

                else:
                    self.__agregar_error(tipo='SINTACTICO',
                                         mensaje='Se esperaba una expresion')

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una orden')

        return False

    def ENTRADA_SALIDA(self):
        if self.__verifica(TOKENS['READ']):
            self.__compara(self.complex.token)
            self.__compara('(')
            if self.DESTINO():
                self.__compara(')')
                self.__compara(';')
                return True

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba un destino')

        elif self.__verifica(TOKENS['WRITE']):
            self.__compara(self.complex.token)
            self.__compara('(')
            if self.EXPRESION():
                self.__compara(')')
                self.__compara(';')
                return True

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una expresion')

        return False

    def RETORNO(self):
        if self.__verifica(TOKENS['RETURN']):
            self.__compara(self.complex.token)
            if self.EXPRESION():
                self.__compara(';')
                return True

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una expresion')

        return False

    def EXPRESION(self):
        if self.__verifica('('):
            self.__compara('(')
            if self.EXPRESION():
                self.__compara(')')
                return True

        elif self.EXPRESION_LOGICA():
            return True

        return False

    #                A -> A                     a               | B
    # EXPRESION_LOGICA -> EXPRESION_LOGICA oplog TERMINO_LOGICO | TERMINO_LOGICO

    # EXPRESION_LOGICA -> TERMINO_LOGICO EXPRESION_LOGICA_PRIMA
    # EXPRESION_LOGICA_PRIMA -> oplog TERMINO_LOGICO EXPRESION_LOGICA_PRIMA | ϵ

    def EXPRESION_LOGICA(self):
        if self.TERMINO_LOGICO():
            if self.EXPRESION_LOGICA_PRIMA():
                return True

        return False

    def EXPRESION_LOGICA_PRIMA(self):
        if self.__verifica('|') or self.__verifica('&'):
            self.__compara(self.complex.token)
            if self.TERMINO_LOGICO():
                if self.EXPRESION_LOGICA_PRIMA():
                    return True

                return False

            return False

        return True

    def TERMINO_LOGICO(self):
        if self.__verifica('!'):
            self.__compara('!')
            self.__compara('(')
            if self.EXPRESION_LOGICA() or self.EXPRESION_RELACIONAL():
                self.__compara(')')
                return True

            return False

        elif self.EXPRESION_RELACIONAL():
            return True

        return False

    # EXPRESION_RELACIONAL -> EXPRESION_RELACIONAL oprel EXPRESION_ARITMETICA | EXPRESION_ARITMETICA

    # EXPRESION_RELACIONAL -> EXPRESION_ARITMETICA EXPRESION_RELACIONAL_PRIMA
    # EXPRESION_RELACIONAL_PRIMA -> oprel EXPRESION_ARITMETICA EXPRESION_RELACIONAL_PRIMA | ϵ

    def EXPRESION_RELACIONAL(self):
        if self.EXPRESION_ARITMETICA():
            if self.EXPRESION_RELACIONAL_PRIMA():
                return True

        return False

    def EXPRESION_RELACIONAL_PRIMA(self):
        if next((True
                 for operador in ('MEN', 'MEI', 'IGU', 'DIF', 'MAI', 'MAY')
                 if self.__verifica(TOKENS[operador])), False):
            self.__compara(self.complex.token)
            if self.EXPRESION_ARITMETICA():
                if self.EXPRESION_RELACIONAL_PRIMA():
                    return True

                return False

            return False

        return True

    # EXPRESION_ARITMETICA -> EXPRESION_ARITMETICA opsumres TERMINO_ARITMETICO | TERMINO_ARITMETICO

    # EXPRESION_ARITMETICA -> TERMINO_ARITMETICO EXPRESION_ARITMETICA_PRIMA
    # EXPRESION_ARITMETICA_PRIMA -> opsumres TERMINO_ARITMETICO EXPRESION_ARITMETICA_PRIMA | ϵ

    def EXPRESION_ARITMETICA(self):
        if self.TERMINO_ARITMETICO():
            if self.EXPRESION_ARITMETICA_PRIMA():
                return True

        return False

    def EXPRESION_ARITMETICA_PRIMA(self):
        if self.__verifica('+') or self.__verifica('-'):
            self.__compara(self.complex.token)
            if self.TERMINO_ARITMETICO():
                if self.EXPRESION_ARITMETICA_PRIMA():
                    return True

                return False

            return False

        return True

    # TERMINO_ARITMETICO -> TERMINO_ARITMETICO opmuldiv FACTOR_ARITMETICO | FACTOR_ARITMETICO

    # TERMINO_ARITMETICO -> FACTOR_ARITMETICO TERMINO_ARITMETICO_PRIMA
    # TERMINO_ARITMETICO_PRIMA -> opmuldiv FACTOR_ARITMETICO TERMINO_ARITMETICO_PRIMA | ϵ

    def TERMINO_ARITMETICO(self):
        if self.FACTOR_ARITMETICO():
            if self.TERMINO_ARITMETICO_PRIMA():
                return True

        return False

    def TERMINO_ARITMETICO_PRIMA(self):
        if next((True for operador in ('/*%\\') if self.__verifica(operador)),
                False):
            self.__compara(self.complex.token)
            if self.FACTOR_ARITMETICO():
                if self.TERMINO_ARITMETICO_PRIMA():
                    return True

                return False

            return False

        return True

    def FACTOR_ARITMETICO(self):
        if self.__verifica('('):
            self.__compara('(')
            if self.EXPRESION_ARITMETICA():
                self.__compara(')')
                return True

            return False

        elif self.OPERANDO():
            return True

        return False

    def OPERANDO(self):
        if next((True for operador in ('NUM', 'NUMF', 'CONST_CHAR', 'CONST_STRING', 'TRUE', 'FALSE')\
            if self.__verifica(TOKENS[operador])), False):
            self.__compara(self.complex.token)
            return True

        elif self.__verifica('('):
            self.__compara('(')
            if self.EXPRESION_ARITMETICA():
                self.__compara(')')
                return True

            return False

        elif self.DESTINO() or self.INVOCAR_FUNCION():
            return True

        return False

    def INVOCAR_FUNCION(self):
        if self.__verifica(TOKENS['CALL']):
            self.__compara(self.complex.token)
            self.__compara(TOKENS['ID'])
            self.__compara('(')
            if self.ACTUALES():
                self.__compara(')')
                return True

            return False

        return False

    # ACTUALES -> ACTUALES, ACTUAL | ACTUAL

    # ACTUALES -> ACTUAL ACTUALES_PRIMA
    # ACTUALES_PRIMA -> , ACTUAL ACTUALES_PRIMA | ϵ

    def ACTUALES(self):
        if self.ACTUAL():
            if self.ACTUALES_PRIMA():
                return True

            return False

        return False

    def ACTUALES_PRIMA(self):
        if self.__verifica(','):
            self.__compara(',')
            if self.ACTUAL():
                if self.ACTUALES_PRIMA():
                    return True

                return False

            return False

        return True

    def ACTUAL(self):
        self.EXPRESION()
        return True

    def PRINCIPAL(self):
        if self.__verifica(TOKENS['MAIN']):
            self.__compara(self.complex.token)
            self.__compara('(')
            if self.PARAMETROS_FORMALES():
                self.__compara(')')
                if self.BLOQUE():
                    return True

                else:
                    self.__agregar_error(
                        tipo='SINTACTICO',
                        mensaje='Se esperaba un bloque de codigo')

        return False
Пример #6
0
class Sintactico(object):
    def __init__(self, codigo=''):
        self.errores = ColeccionError()
        self.lexico = Lexico(codigo=codigo, errores=self.errores)
        self.complex = self.siguiente_componente_lexico()
        self.semantico = Semantico()

    def siguiente_componente_lexico(self):
        self.complex = self.lexico.siguiente_componente_lexico()
        return self.complex

    @property
    def numero_de_linea(self):
        return self.lexico.numero_de_linea

    def __verifica(self, token):
        if isinstance(token, str) and len(token) == 1:
            token = ord(token)

        elif not isinstance(token, int):
            raise ValueError()

        if self.complex is not None:
            return self.complex.token == token

        return False

    def __compara(self, token):
        if isinstance(token, str) and len(token) == 1:
            token = ord(token)

        elif not isinstance(token, int):
            raise ValueError()

        if self.complex is not None and self.complex.token == token:
            self.siguiente_componente_lexico()

        else:
            self.__agregar_error(
                tipo='SINTACTICO',
                mensaje=
                f"Se esperaba: '{chr(token) if token < 256 else TOKENS_INV[token]}'"
            )

    def __agregar_error(self, tipo='SINTACTICO', mensaje=None):
        self.errores.agregar(
            Error(tipo=tipo, num_linea=self.numero_de_linea, mensaje=mensaje))

    def PROGRAMA(self):
        if self.DEFINIR_VARIABLES():
            if self.DEFINIR_FUNCIONES():
                if self.PRINCIPAL():
                    return True

                else:
                    self.__agregar_error(
                        tipo='SINTACTICO',
                        mensaje='Se requiere cuerpo principal del programa')

        return False

    def DEFINIR_VARIABLES(self):
        self.VARIABLES()
        return True

    # VARIABLES -> VARIABLES VARIABLE | VARIABLE
    # VARIABLES -> VARIABLE VARIABLES_PRIMA
    # VARIABLES_PRIMA -> VARIABLE VARIABLES_PRIMA | ϵ

    def VARIABLES(self):
        if self.VARIABLE():
            if self.VARIABLES_PRIMA():
                return True

        return False

    def VARIABLES_PRIMA(self):
        if self.VARIABLE():
            if self.VARIABLES_PRIMA():
                return True

            return False

        return True

    def VARIABLE(self):
        if self.TIPO():
            if self.IDENTIFICADORES():
                self.__compara(';')
                return True

        return False

    def TIPO(self, en_funcion=False):
        tipo = next(
            (x.lower()
             for x in ('INT', 'BOOL', 'FLOAT', 'CHAR', 'STRING', 'VOID')
             if self.__verifica(TOKENS[x])), None)
        if tipo is not None:
            self.lexico.tipo_de_dato_actual = TIPOS[tipo]
            if en_funcion:
                self.lexico.zona_de_codigo = Zonas.DEF_FUNCION
            self.__compara(self.complex.token)
            return True

        return False

    # IDENTIFICADORES -> IDENTIFICADORES , IDENTIFICADOR | IDENTIFICADOR
    # IDENTIFICADORES -> IDENTIFICADOR IDENTIFICADORES_PRIMA
    # IDENTIFICADORES_PRIMA -> , IDENTIFICADOR IDENTIFICADORES_PRIMA | ϵ

    def IDENTIFICADORES(self):
        if self.IDENTIFICADOR():
            if self.IDENTIFICADORES_PRIMA():
                return True

        return False

    def IDENTIFICADORES_PRIMA(self):
        if self.__verifica(','):
            self.__compara(',')
            if self.IDENTIFICADOR():
                if self.IDENTIFICADORES_PRIMA():
                    return True

            return False

        return True

    def IDENTIFICADOR(self):
        if self.__verifica(TOKENS['ID']):
            self.__compara(self.complex.token)
            if self.ES_ARREGLO():
                return True

        return False

    def ES_ARREGLO(self):
        if self.__verifica('['):
            self.lexico.convertir_en_arreglo()
            self.__compara(self.complex.token)
            self.__compara(TOKENS['NUM'])
            self.__compara(']')
            return True

        return True

    def DEFINIR_FUNCIONES(self):
        self.FUNCIONES()
        return True

    # FUNCIONES -> FUNCIONES FUNCION | FUNCION
    # FUNCIONES -> FUNCION FUNCIONES_PRIMA
    # FUNCIONES_PRIMA -> FUNCION FUNCIONES_PRIMA | ϵ

    def FUNCIONES(self):
        if self.FUNCION():
            if self.FUNCIONES_PRIMA():
                return True

        return False

    def FUNCIONES_PRIMA(self):
        if self.FUNCION():
            if self.FUNCIONES_PRIMA():
                return True

            return False

        return True

    def FUNCION(self):
        if self.__verifica(TOKENS['FUNCTION']):
            self.__compara(self.complex.token)
            if self.lexico.fin_definicion_variables_globales is None:
                self.lexico.marcar_posicion(
                    posicion='fin_definicion_variables_globales')

            if self.TIPO(en_funcion=True):
                self.__compara(TOKENS['ID'])
                self.lexico.zona_de_codigo = Zonas.DEF_VARIABLES_LOCALES
                self.lexico.marcar_posicion(
                    posicion='inicio_definicion_variables_locales')
                self.__compara('(')
                if self.PARAMETROS_FORMALES():
                    self.__compara(')')
                    if self.DEFINIR_VARIABLES():
                        self.lexico.marcar_posicion(
                            posicion='fin_definicion_variables_locales')
                        self.lexico.zona_de_codigo = Zonas.CUERPO_FUNCION_LOCAL
                        if self.CUERPO_FUNCION():
                            self.lexico.zona_de_codigo = Zonas.DEF_VARIABLES_GLOBALES
                            return True

        self.lexico.zona_de_codigo = Zonas.DEF_VARIABLES_GLOBALES
        return False

    def PARAMETROS_FORMALES(self):
        self.PARAMETROS()
        return True

    def PARAMETROS(self):
        if self.PARAMETRO():
            if self.PARAMETROS_PRIMA():
                return True

        return False

    def PARAMETROS_PRIMA(self):
        if self.__verifica(','):
            self.__compara(',')
            if self.PARAMETRO():
                if self.PARAMETROS_PRIMA():
                    return True

            return False

        return True

    def PARAMETRO(self):
        if self.TIPO():
            self.__compara(TOKENS['ID'])
            return True

        return False

    def CUERPO_FUNCION(self):
        if self.BLOQUE():
            return True

        return False

    def BLOQUE(self):
        if self.__verifica('{'):
            self.__compara(self.complex.token)
            if self.ORDENES():
                self.__compara('}')
                return True

        return False

    # ORDENES -> ORDENES ORDEN | ORDEN
    # ORDENES -> ORDEN ORDENES_PRIMA
    # ORDENES_PRIMA -> ORDEN ORDENES_PRIMA | ϵ

    def ORDENES(self):
        if self.ORDEN():
            if self.ORDENES_PRIMA():
                return True

        return False

    def ORDENES_PRIMA(self):
        if self.ORDEN():
            if self.ORDENES_PRIMA():
                return True

            return False

        return True

    def ORDEN(self):
        if any((self.ASIGNACION(), self.DECISION(), self.ITERACION(),
                self.ENTRADA_SALIDA(), self.BLOQUE(), self.RETORNO())):
            return True

        return False

    def ASIGNACION(self):
        if self.DESTINO():
            self.__compara(TOKENS['IGU'])
            TAC = self.semantico.pop() + " := "
            if self.FUENTE():
                TAC += self.semantico.pop()
                self.semantico.agregar_codigo_intermedio(TAC)
                self.__compara(';')
                return True

        return False

    def DESTINO(self):
        if self.__verifica(TOKENS['ID']):
            self.semantico.push(self.complex.lexema)
            self.__compara(self.complex.token)
            if self.ELEMENTO_ARREGLO():
                return True

        return False

    def ELEMENTO_ARREGLO(self):
        if self.__verifica('['):
            self.__compara(self.complex.token)
            if self.EXPRESION():
                self.__compara(']')
                return True

            self.__agregar_error(mensaje='Se esperaba una Expresion')
            return False

        return True

    def FUENTE(self):
        if self.EXPRESION():
            return True

        self.__agregar_error(tipo='SINTACTICO',
                             mensaje='Se esperaba una expresion')
        return False

    def DECISION(self):
        if self.__verifica(TOKENS['IF']):
            self.__compara(self.complex.token)
            self.__compara('(')
            if self.EXPRESION():
                self.__compara(')')
                self.__compara(TOKENS['THEN'])
                self.semantico.agregar_codigo_intermedio(
                    f'CMP {self.semantico.pop()}')
                etiqueta = self.semantico.generar_etiqueta()
                self.semantico.agregar_codigo_intermedio(f'JZ {etiqueta}')
                self.semantico.push_etiqueta(etiqueta)
                if self.ORDEN():
                    if self.TIENE_ELSE():
                        return True

                else:
                    self.__agregar_error(tipo='SINTACTICO',
                                         mensaje='Se esperaba una orden')

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una expresion')

        return False

    def TIENE_ELSE(self):
        if self.__verifica(TOKENS['ELSE']):
            etiqueta_else = self.semantico.pop_etiqueta()
            etiqueta_fin = self.semantico.generar_etiqueta()
            self.semantico.push_etiqueta(etiqueta_fin)
            self.semantico.agregar_codigo_intermedio(f'JMP {etiqueta_fin}')
            self.semantico.agregar_codigo_intermedio(f'{etiqueta_else}:')
            self.__compara(self.complex.token)
            if self.ORDEN():
                etiqueta_fin = self.semantico.pop_etiqueta()
                self.semantico.agregar_codigo_intermedio(f'{etiqueta_fin}:')
                return True

            self.__agregar_error(tipo='SINTACTICO',
                                 mensaje='Se esperaba una orden')
            return False

        else:
            etiqueta_fin = self.semantico.pop_etiqueta()
            self.semantico.agregar_codigo_intermedio(f'{etiqueta_fin}:')

        return True

    def ITERACION(self):
        if self.__verifica(TOKENS['FOR']):
            self.__compara(self.complex.token)
            self.__compara(TOKENS['ID'])
            self.__compara(TOKENS['IGU'])
            if self.EXPRESION():
                self.__compara(TOKENS['TO'])
                if self.EXPRESION():
                    if self.ORDEN():
                        return True

                    else:
                        self.__agregar_error(tipo='SINTACTICO',
                                             mensaje='Se esperaba una orden')

                else:
                    self.__agregar_error(tipo='SINTACTICO',
                                         mensaje='Se esperaba una expresion')

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una expresion')

        elif self.__verifica(TOKENS['WHILE']):
            self.__compara(self.complex.token)
            etiqueta_condicion = self.semantico.generar_etiqueta()
            self.semantico.agregar_codigo_intermedio(f'{etiqueta_condicion}:')
            self.__compara('(')
            if self.EXPRESION_LOGICA():
                self.semantico.agregar_codigo_intermedio(
                    f'CMP {self.semantico.pop()}')
                etiqueta_fin = self.semantico.generar_etiqueta()
                self.semantico.agregar_codigo_intermedio(f'JZ {etiqueta_fin}')
                self.__compara(')')
                self.__compara(TOKENS['DO'])
                if self.ORDEN():
                    self.semantico.agregar_codigo_intermedio(
                        f'JMP {etiqueta_condicion}')
                    self.semantico.agregar_codigo_intermedio(
                        f'{etiqueta_fin}:')
                    return True

                else:
                    self.__agregar_error(tipo='SINTACTICO',
                                         mensaje='Se esperaba una orden')

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una expresion')

        elif self.__verifica(TOKENS['DO']):
            if self.ORDEN():
                self.__compara(TOKENS['WHILE'])
                self.__compara('(')
                if self.EXPRESION_LOGICA():
                    self.__compara(')')
                    return True

                else:
                    self.__agregar_error(tipo='SINTACTICO',
                                         mensaje='Se esperaba una expresion')

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una orden')

        return False

    def ENTRADA_SALIDA(self):
        if self.__verifica(TOKENS['READ']):
            self.__compara(self.complex.token)
            self.__compara('(')
            if self.DESTINO():
                self.__compara(')')
                self.__compara(';')
                return True

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba un destino')

        elif self.__verifica(TOKENS['WRITE']):
            self.__compara(self.complex.token)
            self.__compara('(')
            if self.EXPRESION():
                self.semantico.agregar_codigo_intermedio(
                    f'OUT {self.semantico.pop()}')
                self.__compara(')')
                self.__compara(';')
                return True

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una expresion')

        return False

    def RETORNO(self):
        if self.__verifica(TOKENS['RETURN']):
            self.__compara(self.complex.token)
            if self.EXPRESION():
                self.__compara(';')
                return True

            else:
                self.__agregar_error(tipo='SINTACTICO',
                                     mensaje='Se esperaba una expresion')

        return False

    def EXPRESION(self):
        if self.__verifica('('):
            self.__compara('(')
            temp = self.semantico.generar_temporal()
            TAC = f'{temp} := '
            if self.EXPRESION():
                TAC += self.semantico.pop()
                self.semantico.agregar_codigo_intermedio(TAC)
                self.semantico.push(temp)
                self.__compara(')')
                return True

        elif self.EXPRESION_LOGICA():
            return True

        return False

    #                A -> A                     a               | B
    # EXPRESION_LOGICA -> EXPRESION_LOGICA oplog TERMINO_LOGICO | TERMINO_LOGICO

    # EXPRESION_LOGICA -> TERMINO_LOGICO EXPRESION_LOGICA_PRIMA
    # EXPRESION_LOGICA_PRIMA -> oplog TERMINO_LOGICO EXPRESION_LOGICA_PRIMA | ϵ

    def EXPRESION_LOGICA(self):
        if self.TERMINO_LOGICO():
            if self.EXPRESION_LOGICA_PRIMA():
                return True

        return False

    def EXPRESION_LOGICA_PRIMA(self):
        if self.__verifica('|') or self.__verifica('&'):
            operador = self.complex.lexema
            temp = self.semantico.generar_temporal()
            TAC = f'{temp} := {self.semantico.pop()} {operador} '
            self.__compara(self.complex.token)
            if self.TERMINO_LOGICO():
                TAC += self.semantico.pop()
                self.semantico.agregar_codigo_intermedio(TAC)
                self.semantico.push(temp)
                if self.EXPRESION_LOGICA_PRIMA():
                    return True

                return False

            return False

        return True

    def TERMINO_LOGICO(self):
        if self.__verifica('!'):
            self.__compara('!')
            self.__compara('(')
            temp = self.semantico.generar_temporal()
            TAC = f'{temp} := ! '
            if self.EXPRESION_LOGICA() or self.EXPRESION_RELACIONAL():
                TAC += self.semantico.pop()
                self.semantico.agregar_codigo_intermedio(TAC)
                self.semantico.push(temp)
                self.__compara(')')
                return True

            return False

        elif self.EXPRESION_RELACIONAL():
            return True

        return False

    # EXPRESION_RELACIONAL -> EXPRESION_RELACIONAL oprel EXPRESION_ARITMETICA | EXPRESION_ARITMETICA

    # EXPRESION_RELACIONAL -> EXPRESION_ARITMETICA EXPRESION_RELACIONAL_PRIMA
    # EXPRESION_RELACIONAL_PRIMA -> oprel EXPRESION_ARITMETICA EXPRESION_RELACIONAL_PRIMA | ϵ

    def EXPRESION_RELACIONAL(self):
        if self.EXPRESION_ARITMETICA():
            if self.EXPRESION_RELACIONAL_PRIMA():
                return True

        return False

    def EXPRESION_RELACIONAL_PRIMA(self):
        if next((True
                 for operador in ('MEN', 'MEI', 'IGU', 'DIF', 'MAI', 'MAY')
                 if self.__verifica(TOKENS[operador])), False):
            operador = self.complex.lexema
            temp = self.semantico.generar_temporal()
            TAC = f'{temp} := {self.semantico.pop()} {operador} '
            self.__compara(self.complex.token)
            if self.EXPRESION_ARITMETICA():
                TAC += self.semantico.pop()
                self.semantico.agregar_codigo_intermedio(TAC)
                self.semantico.push(temp)
                if self.EXPRESION_RELACIONAL_PRIMA():
                    return True

                return False

            return False

        return True

    # EXPRESION_ARITMETICA -> EXPRESION_ARITMETICA opsumres TERMINO_ARITMETICO | TERMINO_ARITMETICO

    # EXPRESION_ARITMETICA -> TERMINO_ARITMETICO EXPRESION_ARITMETICA_PRIMA
    # EXPRESION_ARITMETICA_PRIMA -> opsumres TERMINO_ARITMETICO EXPRESION_ARITMETICA_PRIMA | ϵ

    def EXPRESION_ARITMETICA(self):
        if self.TERMINO_ARITMETICO():
            if self.EXPRESION_ARITMETICA_PRIMA():
                return True

        return False

    def EXPRESION_ARITMETICA_PRIMA(self):
        if self.__verifica('+') or self.__verifica('-'):
            operador = self.complex.lexema
            temp = self.semantico.generar_temporal()
            TAC = f'{temp} := {self.semantico.pop()} {operador} '
            self.__compara(self.complex.token)
            if self.TERMINO_ARITMETICO():
                TAC += self.semantico.pop()
                self.semantico.agregar_codigo_intermedio(TAC)
                self.semantico.push(temp)
                if self.EXPRESION_ARITMETICA_PRIMA():
                    return True

                return False

            return False

        return True

    # TERMINO_ARITMETICO -> TERMINO_ARITMETICO opmuldiv FACTOR_ARITMETICO | FACTOR_ARITMETICO

    # TERMINO_ARITMETICO -> FACTOR_ARITMETICO TERMINO_ARITMETICO_PRIMA
    # TERMINO_ARITMETICO_PRIMA -> opmuldiv FACTOR_ARITMETICO TERMINO_ARITMETICO_PRIMA | ϵ

    def TERMINO_ARITMETICO(self):
        if self.FACTOR_ARITMETICO():
            if self.TERMINO_ARITMETICO_PRIMA():
                return True

        return False

    def TERMINO_ARITMETICO_PRIMA(self):
        if next((True for operador in ('/*%\\') if self.__verifica(operador)),
                False):
            operador = self.complex.lexema
            temp = self.semantico.generar_temporal()
            TAC = f'{temp} := {self.semantico.pop()} {operador} '
            self.__compara(self.complex.token)
            if self.FACTOR_ARITMETICO():
                TAC += self.semantico.pop()
                self.semantico.agregar_codigo_intermedio(TAC)
                self.semantico.push(temp)
                if self.TERMINO_ARITMETICO_PRIMA():
                    return True

                return False

            return False

        return True

    def FACTOR_ARITMETICO(self):
        if self.__verifica('('):
            self.__compara('(')
            if self.EXPRESION_ARITMETICA():
                self.__compara(')')
                return True

            return False

        elif self.OPERANDO():
            return True

        return False

    def OPERANDO(self):
        if next((True for operador in ('NUM', 'NUMF', 'CONST_CHAR',
                                       'CONST_STRING', 'TRUE', 'FALSE')
                 if self.__verifica(TOKENS[operador])), False):
            self.semantico.push(self.complex.lexema)
            self.__compara(self.complex.token)
            return True

        elif self.__verifica('('):
            self.__compara('(')
            if self.EXPRESION_ARITMETICA():
                self.__compara(')')
                return True

            return False

        elif self.DESTINO() or self.INVOCAR_FUNCION():
            return True

        return False

    def INVOCAR_FUNCION(self):
        if self.__verifica(TOKENS['CALL']):
            self.__compara(self.complex.token)
            self.__compara(TOKENS['ID'])
            self.__compara('(')
            if self.ACTUALES():
                self.__compara(')')
                return True

            return False

        return False

    # ACTUALES -> ACTUALES, ACTUAL | ACTUAL

    # ACTUALES -> ACTUAL ACTUALES_PRIMA
    # ACTUALES_PRIMA -> , ACTUAL ACTUALES_PRIMA | ϵ

    def ACTUALES(self):
        if self.ACTUAL():
            if self.ACTUALES_PRIMA():
                return True

            return False

        return False

    def ACTUALES_PRIMA(self):
        if self.__verifica(','):
            self.__compara(',')
            if self.ACTUAL():
                if self.ACTUALES_PRIMA():
                    return True

                return False

            return False

        return True

    def ACTUAL(self):
        self.EXPRESION()
        return True

    def PRINCIPAL(self):
        if self.__verifica(TOKENS['MAIN']):
            self.__compara(self.complex.token)
            if self.lexico.fin_definicion_variables_globales is None:
                self.lexico.marcar_posicion(
                    posicion='fin_definicion_variables_globales')

            self.lexico.zona_de_codigo = Zonas.CUERPO_PRINCIPAL
            self.__compara('(')
            if self.PARAMETROS_FORMALES():
                self.__compara(')')
                if self.BLOQUE():
                    return True

                else:
                    self.__agregar_error(
                        tipo='SINTACTICO',
                        mensaje='Se esperaba un bloque de codigo')

        return False