Ethgoin's picture
Update parser.py
0179803 verified
from typing import List, Tuple, Any
Token = Tuple[str, str]
FUNCTIONS = {
"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", "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"
}
TYPES = {"int", "float", "boolean"}
class Parser:
def __init__(self, tokens: List[Token]):
self.tokens = tokens
self.pos = 0
self.ast = []
def current(self) -> Token:
return self.tokens[self.pos] if self.pos < len(self.tokens) else ("EOF", "")
def match(self, expected_type: str) -> Token:
if self.current()[0] == expected_type:
tok = self.current()
self.pos += 1
return tok
raise SyntaxError(f"Se esperaba {expected_type} pero se encontr贸 {self.current()}")
def parse(self):
while self.current()[0] != "EOF":
self.ast.append(self.instruction())
return self.ast
def instruction(self) -> Any:
token = self.current()
if token[0] in TYPES:
return self.declaration()
elif token[0] == "IF":
return self.if_statement()
elif token[0] == "WHILE":
return self.while_statement()
elif token[0] in FUNCTIONS:
return self.function_call()
elif token[0] == "IDENTIFIER":
return self.assignment()
else:
raise SyntaxError(f"Instrucci贸n no v谩lida: {token}")
def declaration(self):
tipo = self.match(self.current()[0])[0]
nombre = self.match("IDENTIFIER")[1]
self.match("SEMICOLON")
return {"type": "declaration", "var": nombre, "datatype": tipo}
def assignment(self):
ident = self.match("IDENTIFIER")[1]
self.match("ASSIGN")
expr = self.expression()
self.match("SEMICOLON")
return {"type": "assign", "var": ident, "value": expr}
def if_statement(self):
self.match("IF")
self.match("OPEN_PAREN")
condition = self.expression()
self.match("CLOSE_PAREN")
self.match("THEN")
self.match("OPEN_BRACE")
body = []
while self.current()[0] != "CLOSE_BRACE":
body.append(self.instruction())
self.match("CLOSE_BRACE")
return {"type": "if", "condition": condition, "body": body}
def while_statement(self):
self.match("WHILE")
self.match("OPEN_PAREN")
condition = self.expression()
self.match("CLOSE_PAREN")
self.match("THEN")
self.match("OPEN_BRACE")
body = []
while self.current()[0] != "CLOSE_BRACE":
body.append(self.instruction())
self.match("CLOSE_BRACE")
return {"type": "while", "condition": condition, "body": body}
def function_call(self):
func_name = self.current()[0]
self.match(func_name)
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"
}
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"
}
if func_name in funciones_con_argumento:
if self.current()[0] != "OPEN_PAREN":
raise SyntaxError(f"La funci贸n '{func_name}' requiere un argumento entre par茅ntesis.")
self.match("OPEN_PAREN")
arg = self.expression()
self.match("CLOSE_PAREN")
self.match("SEMICOLON")
return {"type": "function", "name": func_name, "arg": arg}
elif func_name in funciones_sin_argumento:
if self.current()[0] == "OPEN_PAREN":
raise SyntaxError(f"La funci贸n '{func_name}' no debe llevar argumentos ni par茅ntesis.")
self.match("SEMICOLON")
return {"type": "function", "name": func_name, "arg": None}
else:
raise SyntaxError(f"Funci贸n '{func_name}' no reconocida o mal definida.")
def expression(self):
left = self.term()
while self.current()[0] in ("PLUS", "MINUS", "EQUAL", "NOT_EQUAL", "GREATER", "LESS", "AND", "OR"):
op = self.match(self.current()[0])[0]
right = self.term()
left = {"type": "binop", "op": op, "left": left, "right": right}
return left
def term(self):
token_type, token_value = self.current()
if token_type == "IDENTIFIER":
return {"type": "var", "value": self.match("IDENTIFIER")[1]}
elif token_type in ("INT", "FLOAT"):
return {"type": "num", "value": self.match(token_type)[1]}
elif token_type in ("TRUE", "FALSE"):
return {"type": "bool", "value": self.match(token_type)[0]}
elif token_type == "STRING":
return {"type": "string", "value": self.match("STRING")[1]}
elif token_type == "OPEN_PAREN":
self.match("OPEN_PAREN")
expr = self.expression()
self.match("CLOSE_PAREN")
return expr
else:
raise SyntaxError(f"Expresi贸n inv谩lida: {self.current()}")