Analisis-Lenguaje_Robot / semantico.py
Ethgoin's picture
Update semantico.py
f105117 verified
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.")