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)
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()
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()
def __init__(self, codigo=''): self.errores = ColeccionError() self.lexico = Lexico(codigo=codigo, errores=self.errores) self.complex = self.siguiente_componente_lexico()
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
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