Spaces:
Running
Running
class AnalizadorSemantico: | |
def __init__(self, ast): | |
self.ast = ast | |
self.tabla_simbolos = {} | |
self.errores = [] | |
def analizar(self): | |
for nodo in self.ast: | |
self.analizar_instruccion(nodo) | |
return { | |
"variables_declaradas": self.tabla_simbolos, | |
"errores_semanticos": self.errores | |
} | |
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): | |
funciones_sin_argumento = { | |
"START", "REBOOT", "SHUTDOWN" | |
} | |
funciones_con_argumento = { | |
"MOVE_FORWARD", "MOVE_BACKWARD", "PRINT", "SET", | |
"TOGGLE_LIGHT", "CALIBRATE", "ROTATE", "WAIT", | |
"TURN_LEFT", "TURN_RIGHT", "ACTIVATE_SENSOR", "DEACTIVATE_SENSOR" | |
} | |
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.") |