✨
This commit is contained in:
@@ -50,7 +50,7 @@ def num_to_int(n, m):
|
||||
nums = [single_num_to_int(i, m) for i in chars]
|
||||
new_nums = nums.copy()
|
||||
for x, num in enumerate(nums[:-3]):
|
||||
if all(num == nums[x+i] for i in range(0,3)):
|
||||
if all(num == nums[x+i] for i in range(0,4)):
|
||||
raise Exception(n, "is not a valid roman numeral")
|
||||
|
||||
while True:
|
||||
|
||||
@@ -58,7 +58,8 @@ symbol_tokens = [
|
||||
("SYMBOL_PLUS", r"\+"),
|
||||
("SYMBOL_MINUS", r"\-"),
|
||||
("SYMBOL_TIMES", r"\*"),
|
||||
("SYMBOL_DIVIDE", r"\/")
|
||||
("SYMBOL_DIVIDE", r"\/"),
|
||||
("SYMBOL_COMMA", r",")
|
||||
]
|
||||
|
||||
whitespace_tokens = [
|
||||
|
||||
@@ -17,27 +17,24 @@ class Parser():
|
||||
)
|
||||
|
||||
def parse(self, tokens_input) -> ast_nodes.BaseBox:
|
||||
@self.pg.production('program : opt_newline opt_module_calls opt_newline opt_statements opt_newline')
|
||||
|
||||
# Top-level program stuff
|
||||
@self.pg.production('program : opt_newline module_calls statement_list')
|
||||
def program(tokens):
|
||||
return ast_nodes.Program(tokens[1], tokens[3])
|
||||
return ast_nodes.Program(tokens[1], tokens[2])
|
||||
|
||||
@self.pg.production('opt_newline : ')
|
||||
@self.pg.production('opt_newline : NEWLINE')
|
||||
def opt_newline(_):
|
||||
return None
|
||||
|
||||
@self.pg.production('opt_module_calls : ')
|
||||
@self.pg.production('opt_module_calls : module_calls')
|
||||
def opt_module_calls(calls):
|
||||
if len(calls) == 0:
|
||||
return calls
|
||||
else:
|
||||
return calls[0]
|
||||
|
||||
@self.pg.production('module_calls : module_call NEWLINE ')
|
||||
# Module calls
|
||||
@self.pg.production('module_calls : ')
|
||||
@self.pg.production('module_calls : module_call NEWLINE module_calls')
|
||||
def module_calls(calls):
|
||||
if len(calls) == 2:
|
||||
if len(calls) == 0:
|
||||
return []
|
||||
elif len(calls) == 1:
|
||||
return [calls[0]]
|
||||
else:
|
||||
return [calls[0]] + calls[2]
|
||||
@@ -47,17 +44,14 @@ class Parser():
|
||||
return ast_nodes.ModuleCall(tokens[1].value)
|
||||
|
||||
|
||||
@self.pg.production('opt_statements : ')
|
||||
@self.pg.production('opt_statements : statements')
|
||||
def opt_statements(calls):
|
||||
if len(calls) == 0:
|
||||
return calls
|
||||
else:
|
||||
return calls[0]
|
||||
# Statements
|
||||
@self.pg.production('statements : opt_newline statement_list')
|
||||
def statements(tokens):
|
||||
return tokens[1]
|
||||
|
||||
@self.pg.production('statements : statement NEWLINE ')
|
||||
@self.pg.production('statements : statement NEWLINE statements')
|
||||
def statements(calls):
|
||||
@self.pg.production('statement_list : statement opt_newline')
|
||||
@self.pg.production('statement_list : statement NEWLINE statement_list')
|
||||
def statement_list(calls):
|
||||
if len(calls) == 2:
|
||||
return [calls[0]]
|
||||
else:
|
||||
@@ -71,33 +65,77 @@ class Parser():
|
||||
def statement_expression(tokens):
|
||||
return ast_nodes.ExpressionStatement(tokens[0])
|
||||
|
||||
@self.pg.production('expressions : ')
|
||||
@self.pg.production('expressions : expression expressions')
|
||||
def expressions(calls):
|
||||
if len(calls) == 0:
|
||||
return []
|
||||
else:
|
||||
return [calls[0]] + calls[1]
|
||||
@self.pg.production('statement : KEYWORD_DEFINI id ids KEYWORD_VT SYMBOL_LCURL statements SYMBOL_RCURL')
|
||||
def defini(tokens):
|
||||
return ast_nodes.Defini(tokens[1], tokens[2], tokens[5])
|
||||
|
||||
@self.pg.production('ids : ')
|
||||
@self.pg.production('ids : id ids')
|
||||
def ids(calls):
|
||||
if len(calls) == 0:
|
||||
return []
|
||||
@self.pg.production('statement : KEYWORD_REDI expressions')
|
||||
def redi(tokens):
|
||||
return ast_nodes.Redi(tokens[1])
|
||||
|
||||
@self.pg.production('statement : per_statement')
|
||||
@self.pg.production('statement : dum_statement')
|
||||
@self.pg.production('statement : donicum_statement')
|
||||
@self.pg.production('statement : si_statement')
|
||||
def nested_statements(tokens):
|
||||
return tokens[0]
|
||||
|
||||
@self.pg.production('statement : KEYWORD_ERVMPE')
|
||||
def erumpe(_):
|
||||
return ast_nodes.Erumpe()
|
||||
|
||||
@self.pg.production('si_statement : KEYWORD_SI expression KEYWORD_TVNC SYMBOL_LCURL statements SYMBOL_RCURL')
|
||||
@self.pg.production('si_statement : KEYWORD_SI expression KEYWORD_TVNC SYMBOL_LCURL statements SYMBOL_RCURL aluid_statement')
|
||||
def si_statement(tokens):
|
||||
if len(tokens) == 7:
|
||||
return ast_nodes.SiStatement(tokens[1], tokens[4], tokens[6])
|
||||
else:
|
||||
return [calls[0]] + calls[1]
|
||||
return ast_nodes.SiStatement(tokens[1], tokens[4], None)
|
||||
|
||||
@self.pg.production('aluid_statement : KEYWORD_ALVID si_statement')
|
||||
def aluid_si(tokens):
|
||||
return [tokens[1]]
|
||||
|
||||
@self.pg.production('aluid_statement : KEYWORD_ALVID SYMBOL_LCURL statements SYMBOL_RCURL')
|
||||
def aluid(tokens):
|
||||
return tokens[2]
|
||||
|
||||
@self.pg.production('dum_statement : KEYWORD_DVM expression KEYWORD_FACE SYMBOL_LCURL statements SYMBOL_RCURL')
|
||||
def dum(tokens):
|
||||
return ast_nodes.DumStatement(tokens[1], tokens[4])
|
||||
|
||||
@self.pg.production('per_statement : KEYWORD_PER id KEYWORD_IN expression KEYWORD_FACE SYMBOL_LCURL statements SYMBOL_RCURL')
|
||||
def per(tokens):
|
||||
return ast_nodes.PerStatement(tokens[3], tokens[1], tokens[6])
|
||||
|
||||
@self.pg.production('donicum_statement : KEYWORD_DONICVM id KEYWORD_VT expression KEYWORD_VSQVE expression KEYWORD_FACE SYMBOL_LCURL statements SYMBOL_RCURL')
|
||||
def donicum(tokens):
|
||||
range_array = ast_nodes.DataRangeArray(tokens[3], tokens[5])
|
||||
return ast_nodes.PerStatement(range_array, tokens[1], tokens[8])
|
||||
|
||||
# expressions
|
||||
@self.pg.production('expressions : SYMBOL_LPARENS expression_list')
|
||||
def expressions(tokens):
|
||||
return tokens[1]
|
||||
|
||||
@self.pg.production('expression_list : SYMBOL_RPARENS')
|
||||
@self.pg.production('expression_list : expression SYMBOL_RPARENS')
|
||||
@self.pg.production('expression_list : expression SYMBOL_COMMA expression_list')
|
||||
def expression_list(calls):
|
||||
if len(calls) == 1:
|
||||
return []
|
||||
elif len(calls) == 2:
|
||||
return [calls[0]]
|
||||
else:
|
||||
return [calls[0]] + calls[2]
|
||||
|
||||
@self.pg.production('expression : id')
|
||||
def expression_id(tokens):
|
||||
return tokens[0]
|
||||
|
||||
@self.pg.production('statement : KEYWORD_DEFINI id ids KEYWORD_VT SYMBOL_LCURL opt_newline opt_statements opt_newline SYMBOL_RCURL')
|
||||
def defini(tokens):
|
||||
return ast_nodes.Defini(tokens[1], tokens[2], tokens[6])
|
||||
|
||||
@self.pg.production('statement : KEYWORD_REDI expressions')
|
||||
def redi(tokens):
|
||||
return ast_nodes.Redi(tokens[1])
|
||||
@self.pg.production('expression : BUILTIN expressions')
|
||||
def expression_builtin(tokens):
|
||||
return ast_nodes.BuiltIn(tokens[0].value, tokens[1])
|
||||
|
||||
@self.pg.production('expression : DATA_STRING')
|
||||
def expression_string(tokens):
|
||||
@@ -126,61 +164,10 @@ class Parser():
|
||||
def binop(tokens):
|
||||
return ast_nodes.BinOp(tokens[0], tokens[2], tokens[1].name)
|
||||
|
||||
@self.pg.production('expression : BUILTIN expressions')
|
||||
def expression_builtin(tokens):
|
||||
return ast_nodes.BuiltIn(tokens[0].value, tokens[1])
|
||||
|
||||
@self.pg.production("id : ID")
|
||||
def id_expression(tokens):
|
||||
return ast_nodes.ID(tokens[0].value)
|
||||
|
||||
@self.pg.production('expression : KEYWORD_INVOCA id expressions')
|
||||
def invoca(tokens):
|
||||
return ast_nodes.Invoca(tokens[1], tokens[2])
|
||||
|
||||
@self.pg.production('statement : si_statement')
|
||||
def si_statement(tokens):
|
||||
return tokens[0]
|
||||
|
||||
@self.pg.production('statement : per_statement')
|
||||
@self.pg.production('statement : dum_statement')
|
||||
@self.pg.production('statement : donicum_statement')
|
||||
def loops(tokens):
|
||||
return tokens[0]
|
||||
|
||||
@self.pg.production('statement : KEYWORD_ERVMPE')
|
||||
def erumpe(_):
|
||||
return ast_nodes.Erumpe()
|
||||
|
||||
@self.pg.production('si_statement : KEYWORD_SI expression KEYWORD_TVNC SYMBOL_LCURL opt_newline opt_statements opt_newline SYMBOL_RCURL opt_newline aluid_statement')
|
||||
def si(tokens):
|
||||
return ast_nodes.SiStatement(tokens[1], tokens[5], tokens[9])
|
||||
|
||||
@self.pg.production('dum_statement : KEYWORD_DVM expression KEYWORD_FACE SYMBOL_LCURL opt_newline opt_statements opt_newline SYMBOL_RCURL')
|
||||
def dum(tokens):
|
||||
return ast_nodes.DumStatement(tokens[1], tokens[5])
|
||||
|
||||
@self.pg.production('per_statement : KEYWORD_PER id KEYWORD_IN expression KEYWORD_FACE SYMBOL_LCURL opt_newline opt_statements opt_newline SYMBOL_RCURL')
|
||||
def per(tokens):
|
||||
return ast_nodes.PerStatement(tokens[3], tokens[1], tokens[7])
|
||||
|
||||
@self.pg.production('donicum_statement : KEYWORD_DONICVM id KEYWORD_VT expression KEYWORD_VSQVE expression KEYWORD_FACE SYMBOL_LCURL opt_newline opt_statements opt_newline SYMBOL_RCURL')
|
||||
def donicum(tokens):
|
||||
range_array = ast_nodes.DataRangeArray(tokens[3], tokens[5])
|
||||
return ast_nodes.PerStatement(range_array, tokens[1], tokens[9])
|
||||
|
||||
@self.pg.production('aluid_statement : ')
|
||||
def aluid_empty(_):
|
||||
return None
|
||||
|
||||
@self.pg.production('aluid_statement : KEYWORD_ALVID si_statement')
|
||||
def aluid_si(tokens):
|
||||
return [tokens[1]]
|
||||
|
||||
@self.pg.production('aluid_statement : KEYWORD_ALVID SYMBOL_LCURL opt_newline opt_statements opt_newline SYMBOL_RCURL aluid_statement')
|
||||
def aluid(tokens):
|
||||
return tokens[3]
|
||||
|
||||
@self.pg.production('expression : SYMBOL_LPARENS expression SYMBOL_RPARENS')
|
||||
def parens(tokens):
|
||||
return tokens[1]
|
||||
@@ -193,9 +180,29 @@ class Parser():
|
||||
def range_array(tokens):
|
||||
return ast_nodes.DataRangeArray(tokens[1], tokens[3])
|
||||
|
||||
# @self.pg.error
|
||||
# def error_handle(token):
|
||||
# raise ValueError(token)
|
||||
# ids
|
||||
@self.pg.production('ids : SYMBOL_LPARENS id_list')
|
||||
def ids(tokens):
|
||||
return tokens[1]
|
||||
|
||||
@self.pg.production('id_list : SYMBOL_RPARENS')
|
||||
@self.pg.production('id_list : id SYMBOL_RPARENS')
|
||||
@self.pg.production('id_list : id SYMBOL_COMMA id_list')
|
||||
def id_list(calls):
|
||||
if len(calls) == 1:
|
||||
return []
|
||||
elif len(calls) == 2:
|
||||
return [calls[0]]
|
||||
else:
|
||||
return [calls[0]] + calls[2]
|
||||
|
||||
@self.pg.production("id : ID")
|
||||
def id_expression(tokens):
|
||||
return ast_nodes.ID(tokens[0].value)
|
||||
|
||||
@self.pg.error
|
||||
def error_handle(token):
|
||||
raise Exception(token.name, token.value, token.source_pos)
|
||||
|
||||
parser = self.pg.build()
|
||||
return parser.parse(tokens_input)
|
||||
|
||||
Reference in New Issue
Block a user