Spaces:
Running
Running
| FUNCIONES_VALIDAS = { | |
| "ACTIVATE_ALARM": "Activa la alarma del robot", | |
| "ACTIVATE_SENSOR": "Activa el sensor del robot", | |
| "BREAK": "Interrumpe el ciclo actual", | |
| "CHARGE_BATTERY": "Inicia la carga de bater铆a del robot", | |
| "CHECK_BATTERY": "Verifica el nivel de bater铆a", | |
| "CLOSE_DOOR": "Cierra la puerta del robot", | |
| "CONTINUE": "Contin煤a al siguiente ciclo", | |
| "DEACTIVATE_ALARM": "Desactiva la alarma", | |
| "DEACTIVATE_SENSOR": "Desactiva el sensor", | |
| "DECREASE_SPEED": "Disminuye la velocidad actual", | |
| "DOWNLOAD": "Inicia la descarga de datos", | |
| "REBOOT": "Reinicia el sistema del robot", | |
| "READ_SENSOR": "Lee un sensor", | |
| "RESET": "Reinicia las configuraciones", | |
| "RESUME": "Reanuda la ejecuci贸n previa", | |
| "REVERSE": "Invierte el sentido de movimiento", | |
| "SHUTDOWN": "Apaga el sistema del robot", | |
| "SHUT_OFF": "Desconecta inmediatamente", | |
| "START": "Inicia el programa principal", | |
| "STOP": "Detiene el movimiento actual", | |
| "STOP_IMMEDIATELY": "Frena inmediatamente", | |
| "TOGGLE_LIGHT": "Cambia el estado de la luz", | |
| "TURN_DOWN": "Inclina hacia abajo", | |
| "TURN_LEFT": "Gira a la izquierda", | |
| "TURN_RIGHT": "Gira a la derecha", | |
| "TURN_UP": "Inclina hacia arriba", | |
| "UNLOCK": "Desbloquea el acceso", | |
| "LOG": "Registra una entrada en el log", | |
| "INIT": "Inicializa el sistema", | |
| "LOCK": "Bloquea el acceso", | |
| "LOW_BATTERY": "Indica bater铆a baja", | |
| "OPEN_DOOR": "Abre la puerta", | |
| "PAUSE": "Pausa temporal del programa", | |
| "CALIBRATE": "Calibra un sensor o componente", | |
| "COPY_FILE": "Copia un archivo en el sistema", | |
| "DELETE_FILE": "Elimina un archivo del sistema", | |
| "MOVE_BACKWARD": "El robot se mover谩 hacia atr谩s", | |
| "MOVE_FORWARD": "El robot se mover谩 hacia adelante", | |
| "MOVE_TO": "El robot se mover谩 a una posici贸n espec铆fica", | |
| "PRINT": "Imprime un mensaje en pantalla", | |
| "RENAME_FILE": "Cambia el nombre de un archivo", | |
| "ROTATE": "Gira en su eje cierto n煤mero de grados", | |
| "SAVE_FILE": "Guarda informaci贸n en un archivo", | |
| "SCAN": "Escanea el entorno", | |
| "SET": "Establece una variable o configuraci贸n", | |
| "SET_SPEED": "Establece una nueva velocidad", | |
| "UPLOAD": "Sube informaci贸n al servidor", | |
| "UPLOAD_FILE": "Sube un archivo al servidor", | |
| "WAIT": "Hace una pausa durante X tiempo" | |
| } | |
| class AnalizadorSemantico: | |
| def __init__(self, ast): | |
| self.ast = ast | |
| self.tabla_simbolos = {} | |
| self.errores = [] | |
| self.anotaciones = [] | |
| def analizar(self): | |
| for nodo in self.ast: | |
| self.analizar_instruccion(nodo) | |
| return { | |
| "variables_declaradas": self.tabla_simbolos, | |
| "errores_semanticos": self.errores, | |
| "anotaciones": self.anotaciones | |
| } | |
| def analizar_instruccion(self, nodo): | |
| tipo = nodo["type"] | |
| if tipo == "declaration": | |
| var = nodo["var"] | |
| dtype = nodo["datatype"] | |
| if var in self.tabla_simbolos: | |
| self.errores.append(f"Variable '{var}' ya fue declarada.") | |
| else: | |
| self.tabla_simbolos[var] = dtype | |
| elif tipo == "assign": | |
| if nodo["var"] not in self.tabla_simbolos: | |
| self.errores.append(f"Variable '{nodo['var']}' usada sin declarar.") | |
| return | |
| tipo_valor = self.analizar_expresion(nodo["value"]) | |
| tipo_var = self.tabla_simbolos[nodo["var"]] | |
| if tipo_valor != tipo_var and tipo_valor != "error": | |
| self.errores.append(f"Tipo incompatible en asignaci贸n a '{nodo['var']}': {tipo_var} = {tipo_valor}") | |
| elif tipo in ("if", "while"): | |
| tipo_cond = self.analizar_expresion(nodo["condition"]) | |
| if tipo_cond != "boolean": | |
| self.errores.append(f"La condici贸n de '{tipo}' debe ser tipo boolean, no '{tipo_cond}'") | |
| for instr in nodo["body"]: | |
| self.analizar_instruccion(instr) | |
| elif tipo == "function": | |
| self.validar_funcion(nodo["name"], nodo["arg"]) | |
| else: | |
| self.errores.append(f"Instrucci贸n no reconocida: {nodo}") | |
| def analizar_expresion(self, expr): | |
| tipo = expr["type"] | |
| if tipo == "num": | |
| return "float" if "." in expr["value"] else "int" | |
| elif tipo == "var": | |
| nombre = expr["value"] | |
| if nombre not in self.tabla_simbolos: | |
| self.errores.append(f"Variable '{nombre}' usada sin declarar.") | |
| return "error" | |
| return self.tabla_simbolos[nombre] | |
| elif tipo == "binop": | |
| tipo_izq = self.analizar_expresion(expr["left"]) | |
| tipo_der = self.analizar_expresion(expr["right"]) | |
| if tipo_izq != tipo_der: | |
| self.errores.append(f"Tipos incompatibles: {tipo_izq} y {tipo_der}") | |
| return "error" | |
| if expr["op"] in ("EQUAL", "NOT_EQUAL", "GREATER", "LESS"): | |
| return "boolean" | |
| return tipo_izq | |
| elif tipo == "bool": | |
| return "boolean" | |
| elif tipo == "string": | |
| return "string" | |
| else: | |
| self.errores.append(f"Expresi贸n no v谩lida: {expr}") | |
| return "error" | |
| def validar_funcion(self, nombre, arg): | |
| if nombre not in FUNCIONES_VALIDAS: | |
| self.errores.append(f"Funci贸n '{nombre}' no reconocida.") | |
| return | |
| descripcion = FUNCIONES_VALIDAS[nombre] | |
| self.anotaciones.append(f"{nombre}: {descripcion}") | |
| funciones_sin_argumento = { | |
| "ACTIVATE_ALARM", "ACTIVATE_SENSOR", "BREAK", "CHARGE_BATTERY", "CHECK_BATTERY", | |
| "CLOSE_DOOR", "CONTINUE", "DEACTIVATE_ALARM", "DEACTIVATE_SENSOR", "DECREASE_SPEED", | |
| "DOWNLOAD", "REBOOT", "READ_SENSOR", "RESET", "RESUME", "REVERSE", "SHUTDOWN", | |
| "SHUT_OFF", "START", "STOP", "STOP_IMMEDIATELY", "TOGGLE_LIGHT", "TURN_DOWN", | |
| "TURN_LEFT", "TURN_RIGHT", "TURN_UP", "UNLOCK", "LOG", "INIT", "LOCK", "LOW_BATTERY", | |
| "OPEN_DOOR", "PAUSE" | |
| } | |
| funciones_con_argumento = { | |
| "CALIBRATE", "COPY_FILE", "DELETE_FILE", "MOVE_BACKWARD", "MOVE_FORWARD", "MOVE_TO", | |
| "PRINT", "RENAME_FILE", "ROTATE", "SAVE_FILE", "SCAN", "SET", "SET_SPEED", "UPLOAD", | |
| "UPLOAD_FILE", "WAIT" | |
| } | |
| if nombre in funciones_sin_argumento: | |
| if arg is not None: | |
| self.errores.append(f"La funci贸n '{nombre}' no debe tener argumentos.") | |
| elif nombre in funciones_con_argumento: | |
| if arg is None: | |
| self.errores.append(f"La funci贸n '{nombre}' requiere un argumento.") | |
| else: | |
| self.analizar_expresion(arg) | |
| else: | |
| self.errores.append(f"Funci贸n '{nombre}' no reconocida.") |