def is_formal_parameter_section(cls, tk_list: list) -> dict: i = 1 if tk_list[0] == "<KEYWORD_VAR>" else 0 if (len(tk_list) > 2 and tk_list[i] == "<IDENTIFIER_LIST>" and tk_list[-2] == "<COLON>" and tk_list[-1] == "<SIMPLE_TYPE>"): return Token_("", "<FORMAL_PARAMETERS_SECTION>", None) return Token_("", None, None)
def is_formal_parameters(tk_list, i): initial = i errors = [] tk_atual = Convert(tk_list, i) if tk_list[i][1] == "<OPEN_PARENTHESIS>": res, e = Analyzers2.is_formal_parameter_section(tk_list, i + 1) if res.token == "<FORMAL_PARAMETER_SECTION>": i = res.col[1] while i < len(tk_list) and i + 1 < len(tk_list): res, e = Analyzers2.is_formal_parameter_section(tk_list, i + 1) if ( tk_list[i][1] == "<COMMAND_END>" and res.token == "<FORMAL_PARAMETERS>" ): i += res.col[1] + 2 else: break if tk_list[i][1] == "<CLOSE_PARENTHESIS>": return ( Token_(tk_list[initial:i], "<FORMAL_PARAMETERS>", (initial, i)), errors, ) return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_procedure_call(tk_list: list, i: int): initial = i errors = [] l = len(tk_list) tk_atual = Convert(tk_list, i) if i < l and tk_list[i][1] == "<IDENTIFIER>": procedure = tk_list[i][1] i += 1 res, e = Analyzers2.is_expression_list(tk_list, i + 1) if ( tk_list[i][1] == "<OPEN_PARENTHESIS>" and res.token == "<EXPRESSION_LIST>" and tk_list[res.col[1] + 1][1] == "<CLOSE_PARENTHESIS>" ): parameters = res.lexem print(parameters) i += res.col[1] + 1 Analyzers2.semantic_analyzer.validate_procedure_call( procedure, parameters ) return ( Token_(tk_list[initial:i], "<PROCEDURE_CALL>", (initial, i + 1)), errors, ) return Token_(tk_list[initial:i], "<ERROR>", (initial, i + 1)), errors
def is_simple_expression(tk_list: list, i: int): initial = i errors = [] l = len(tk_list) tk_atual = Convert(tk_list, i) has_sign = False if i < l and ( tk_list[i][1] == "<PLUS_SIGN>" or tk_list[i][1] == "<MINUS_SIGN>" ): has_sign = True res, e = Analyzers2.is_therm(tk_list, i + 1 if has_sign else i) if res.token == "<THERM>": i = res.col[1] errors.extend(e) while i + 1 < len(tk_list): res, e = Analyzers2.is_therm(tk_list, i + 1) if ( tk_list[i][1] == "<PLUS_SIGN>" or tk_list[i][1] == "<MINUS_SIGN>" or tk_list[i][1] == "<KEYWORD_OR>" ) and res.token == "<THERM>": i = res.col[1] errors.extend(e) else: break return ( Token_(tk_list[initial:i], "<SIMPLE_EXPRESSION>", (initial, i)), errors, ) return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_simple_expression(cls, tk_list: list) -> Token_: len_tk_list = len(tk_list) if len_tk_list >= 1 and tk_list[0] in [ "<THERM>", "<PLUS_SIGN>", "<MINUS_SIGN>", ]: i = 1 if tk_list[0] != "<THERM>": i += 1 if tk_list[1] != "<THERM>": return Token_("", None, None) checked = True while True: if i < len_tk_list: if not (tk_list[i] in ["<PLUS_SIGN>", "<MINUS_SIGN>", "<KEYWORD_OR>"] and (i + 1 < len_tk_list and tk_list[i + 1] == "<THERM>")): checked = False break else: break i += 2 if checked: return Token_(tk_list, "<SIMPLE_EXPRESSION>", None) return Token_("", None, None)
def is_therm(tk_list: list, i: int): initial = i errors = [] l = len(tk_list) tk_atual = Convert(tk_list, i) res, e = Analyzers2.is_factor(tk_list, i) if res.token == "<FACTOR>": i = res.col[1] errors.extend(e) while i + 1 < len(tk_list): res, e = Analyzers2.is_factor(tk_list, i + 1) if ( i < l and tk_list[i][1] in ["<MULTIPLICATION_SIGN>", "<DIVISION_SIGN>", "<KEYWORD_AND>"] and res.token == "<FACTOR>" ): i = res.col[1] errors.extend(e) else: break return Token_(tk_list[initial:i], "<THERM>", (initial, i)), errors return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_subroutine_declaration_part(tk_list: list, i: int): initial = i errors = [] tk_atual = Convert(tk_list, i) res, e = Analyzers2.is_procedure_declaration(tk_list, i) if ( res.col[1] + 1 < len(tk_list) and tk_list[res.col[1] + 1][1] == "<COMMAND_END>" and res.token == "<PROCEDURE_DECLARATION>" ): i = res.col[1] + 2 while i + 1 < len(tk_list): res, e = Analyzers2.is_procedure_declaration(tk_list, i) if ( tk_list[i + 1][1] == "<COMMAND_END>" and res.token == "<PROCEDURE_DECLARATION>" ): i += res.col[1] + 2 else: break return ( Token_( tk_list[initial:i], "<SUBROUTINE_DECLARATION_PART>", (initial, i) ), errors, ) return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_program(cls, tk_list: list) -> Token_: if (len(tk_list) == 5 and tk_list[0] == "<KEYWORD_PROGRAM>" and tk_list[1] == "<IDENTIFIER>" and tk_list[2] == "<COMMAND_END>" and tk_list[3] == "<BLOC>" and tk_list[4] == "<DOT>"): return Token_("", "<PROGRAM>", None) return Token_("", None, None)
def is_formal_parameter_section(tk_list, i): initial = i errors = [] tk_atual = Convert(tk_list, i) if tk_list[i][1] == "<KEYWORD_VAR>": res, e = Analyzers2.is_identifier_list(tk_list, i + 1) if res.token == "<IDENTIFIER_LIST>": value = res.lexem i = res.col[1] if tk_list[i][1] == "<COLON>": i += 1 if tk_list[i][1] == "<SIMPLE_TYPE>": simple_type = tk_list[i][0] i += 1 Analyzers2.semantic_analyzer.insert_parameters( value=value, variable_type=simple_type ) return ( Token_( tk_list[initial:i], "<FORMAL_PARAMETER_SECTION>", (initial, i), ), errors, ) return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_variable_declaration_part(tk_list: list, i: int): initial = i errors = [] tk_atual = Convert(tk_list, i) errors = [] first, e = Analyzers2.is_variable_declarator(tk_list, i) # print(f"first-lexem{first.lexem}") # input() if first.token == "<VARIABLE_DECLARATION>": i = first.col[1] while i < len(tk_list) and i + 1 < len(tk_list): next, e = Analyzers2.is_variable_declarator(tk_list, i + 1) # print(next.token) # input() if ( tk_list[i][1] == "<COMMAND_END>" and next.token == "<VARIABLE_DECLARATION>" ): i = next.col[1] else: break # print(tk_list[i][1]) if i < len(tk_list) and tk_list[i][1] == "<COMMAND_END>": return ( Token_( tk_list[initial:i], "<VARIABLE_DECLARATION_PART>", (initial, i + 1), ), errors, ) return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_factor(cls, tk_list: list) -> Token_: if (tk_list == ["<VARIABLE>"] or tk_list == ["<NUMBER>"] or tk_list == [ "<OPEN_PARENTHESIS>", "<EXPRESSION>", "<CLOSE_PARENTHESIS>" ] or tk_list == ["<KEYWORD_NOT>", "<FACTOR>"]): return Token_("", "<FACTOR>", None) return Token_("", None, None)
def is_procedure_declaration(cls, tk_list: list) -> dict: if (3 < len(tk_list) <= 5 and tk_list[0] == "<KEYWORD_PROCEDURE>" and tk_list[1] == "<IDENTIFIER>" and tk_list[-2] == "<COMMAND_END>" and tk_list[-1] == "<BLOC>"): if len(tk_list) == 5 and tk_list[2] != "<FORMAL_PARAMETERS>": return Token_("", None, None) return Token_("", "<PROCEDURE_DECLARATION>", None) return Token_("", None, None)
def is_composite_command(tk_list: list, i: int): initial = i errors = [] l = len(tk_list) tk_atual = Convert(tk_list, i) if i < l and tk_list[i][1] == "<KEYWORD_BEGIN>": i += 1 else: errors.append({"message": "begin expected", "line": "0", "col": "0"}) i = Analyzers2.error( i + 1, tk_list, [ "<IDENTIFIER>", "<KEYWORD_BEGIN>", "<KEYWORD_IF>", "<KEYWORD_PROCEDURE>", "<KEYWORD_WHILE>", ], limit=1, ) if i < l: res, e = Analyzers2.is_command(tk_list, i) if res.token == "<COMMAND>": i = res.col[1] errors.extend(e) while i + 1 < l: res, e = Analyzers2.is_command(tk_list, i + 1) if ( i < l and tk_list[i][1] == "<COMMAND_END>" and res.token == "<COMMAND>" ): i = res.col[1] errors.extend(e) else: break if i < l and tk_list[i][1] == "<KEYWORD_END>": return ( Token_(tk_list[initial:i], "<COMPOSITE_COMMAND>", (initial, i)), errors, ) else: errors.append({"message": "end expected", "line": "0", "col": "0"}) i = Analyzers2.error( i + 1, tk_list, ["<KEYWORD_END>"], ) return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_variable(tk_list: list, i: int): initial = i errors = [] l = len(tk_list) tk_atual = Convert(tk_list, i) if i < l and tk_list[i][1] == "<IDENTIFIER>": # res, e = Analyzers2.is_expression(tk_list, i + 1) # if res.token == "<EXPRESSION>": # i = res.col[1] return Token_(tk_list[initial:i], "<VARIABLE>", (initial, i + 1)), errors return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_identifier_list(tk_list: list, i: int): initial = i errors = [] tk_atual = Convert(tk_list, i) if tk_list[i][1] == "<IDENTIFIER>": i += 1 while i + 1 < len(tk_list): if tk_list[i][1] == "<COMMA>" and tk_list[i + 1][1] == "<IDENTIFIER>": i += 2 else: break return Token_(tk_list[initial:i], "<IDENTIFIER_LIST>", (initial, i)), errors return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_subroutines_declaration_part(cls, tk_list: list) -> dict: i = 0 checked = True while True: if i < len(tk_list): if (tk_list[i] != "<PROCEDURE_DECLARATION>" or tk_list[i + 1] != "<COMMAND_END>"): checked = False else: break i += 2 if checked: return Token_(tk_list, "<SUBROUTINES_DECLARATION_PART>", None) else: return Token_("", None, None)
def is_expression_list(tk_list: list, i: int): initial = i errors = [] tk_atual = Convert(tk_list, i) res, e = Analyzers2.is_expression(tk_list, i) if res.token == "<EXPRESSION>": i += res.col[1] + 1 # TODO: verificar finalização de indice while i < len(tk_list) and i + 1 < len(tk_list): res, e = Analyzers2.is_expression(tk_list, i + 1) if tk_list[i][1] == "<COMMA>" and res.token == "<EXPRESSION>": i += res.col[1] + 2 else: break return Token_(tk_list[initial:i], "<IDENTIFIER_LIST>", (initial, i)), errors return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_program(tk_list: list, i: int): initial = i errors = [] l = len(tk_list) errors = [] tk_atual = Convert(tk_list, i) if i < l and tk_list[i][1] == "<KEYWORD_PROGRAM>": i += 1 else: errors.append({"message": "program expected ", "line": "0", "col": "0"}) i = Analyzers2.error(i + 1, tk_list, ["<IDENTIFIER>"]) if i < l and tk_list[i][1] == "<IDENTIFIER>": i += 1 else: errors.append( {"message": "program identifier expected", "line": "0", "col": "0"} ) i = Analyzers2.error(i, tk_list, ["<COMMAND_END>"], limit=2) if i < l and tk_list[i][1] == "<COMMAND_END>": i += 1 else: errors.append({"message": "';' expected", "line": "0", "col": "0"}) i = Analyzers2.error( i, tk_list, [ "<SIMPLE_TYPE>", "<KEYWORD_VAR>", "<KEYWORD_PROCEDURE>", "<KEYWORD_BEGIN>", ], limit=2, ) if i < l: res, e = Analyzers2.is_bloc(tk_list, i) errors.extend(e) i = res.col[1] + 1 # get the end of the block plus 1 if res.token == "<BLOC>": pass if i < l and tk_list[i][1] == "<DOT>": i += 1 else: errors.append( { "message": "'.' expected on the end of program", "line": "0", "col": "0", } ) Analyzers2.error(i + 1, tk_list, []) return Token_(tk_list[initial:i], "<PROGRAM>", (initial, i + 1)), errors
def is_variable_declarator(tk_list, i): initial = i errors = [] tk_atual = Convert(tk_list, i) # print(tk_list[i][1]) # input() if tk_list[i][1] == "<SIMPLE_TYPE>": is_ilist, e = Analyzers2.is_identifier_list(tk_list, i + 1) simple_type = tk_list[i][0] i = is_ilist.col[1] if is_ilist.token == "<IDENTIFIER_LIST>": token = Token_( tk_list[initial:i], "<VARIABLE_DECLARATION>", (initial, i) ) Analyzers2.semantic_analyzer.insert_identifiers( value=is_ilist.lexem, variable_type=simple_type ) return token, errors return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_part_var_declaration(cls, tk_list: list) -> dict: checked = False i = 0 while True: if i < len(tk_list): if tk_list[i] == "<VAR_DECLARATION>": checked = True else: break if i + 1 < len(tk_list) and tk_list[i + 1] == "<COMMAND_END>": checked = False i += 1 else: break i += 1 if checked: return Token_(tk_list, "<VAR_DECLARATION_PART>", None) else: return Token_("", None, None)
def is_expression(cls, tk_list: list) -> Token_: len_tk_list = len(tk_list) if len_tk_list >= 1 and tk_list[0] == "<SIMPLE_EXPRESSION>": i = 1 checked = True while i < len_tk_list: if not (tk_list[i] == "<RELATION>" and (i + 1 < len_tk_list and tk_list[i + 1] == "<SIMPLE_EXPRESSION>")): checked = False break i += 2 if checked: return Token_(tk_list, "<SIMPLE_EXPRESSION>", None) return Token_("", None, None)
def is_expression_list(cls, tk_list: list): checked = False i = 0 while True: if i < len(tk_list): # print(i, i+1) if tk_list[i] == "<EXPRESSION>": checked = True else: break if i + 1 < len(tk_list) and tk_list[i + 1] == "<COMMA>": checked = False i += 1 else: break i += 1 if checked: return Token_(tk_list, "<EXPRESSION_LIST>", None) else: return Token_("", None, None)
def is_identifier_list(cls, tk_list: list) -> dict: checked = False i = 0 while True: if i < len(tk_list): # print(i, i+1) if tk_list[i] == "<IDENTIFIER>": checked = True else: break if i + 1 < len(tk_list) and tk_list[i + 1] == "<COMMA>": checked = False i += 1 else: break i += 1 if checked: return Token_(tk_list, "<IDENTIFIER_LIST>", None) else: return Token_("", None, None)
def is_repetitive_command(tk_list: list, i: int): # verificar se dá pra analisar erro com o while initial = i errors = [] l = len(tk_list) tk_atual = Convert(tk_list, i) if i < l and tk_list[i][1] == "<KEYWORD_WHILE>": res, e = Analyzers2.is_expression(tk_list, i + 1) if res.token == "<EXPRESSION>": i = res.col[1] errors.extend(e) if tk_list[i][1] == "<KEYWORD_DO>": i += 1 else: errors.append({"message": "'do' expected", "line": "0", "col": "0"}) i = Analyzers2.error( i + 1, tk_list, [ "<IDENTIFIER>", "<KEYWORD_IF>", "<KEYWORD_PROCEDURE>", "<KEYWORD_WHILE>", ], limit=1, ) res, e = Analyzers2.is_command(tk_list, i) if res.token == "<COMMAND>": i = res.col[1] return ( Token_( tk_list[initial:i], "<REPETITIVE_COMMAND_1>", (initial, i) ), errors, ) # ACHO QUE AQUI QUE FAREMOS A BUSCA DO FOLLOW i = Analyzers2.error( i, tk_list, ["<KEYWORD_END>", "<COMMAND_END>", "<KEYWORD_ELSE>"] ) return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_bloc(tk_list: list, i: int): initial = i errors = [] tk_atual = Convert(tk_list, i) res, e = Analyzers2.is_variable_declaration_part(tk_list, i) if res.token == "<VARIABLE_DECLARATION_PART>": i = res.col[1] errors.extend(e) res, e = Analyzers2.is_subroutine_declaration_part(tk_list, i) if res.token == "<SUBROUTINE_DECLARATION_PART>": i = res.col[1] errors.extend(e) res, e = Analyzers2.is_composite_command(tk_list, i) if res.token == "<COMPOSITE_COMMAND>": i = res.col[1] errors.extend(e) return Token_(tk_list[initial:i], "<BLOC>", (initial, i)), errors return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_procedure_declaration(tk_list, i): initial = i errors = [] tk_atual = Convert(tk_list, i) if tk_list[i][1] == "<KEYWORD_PROCEDURE>": procedure = tk_list[i + 1][0] Analyzers2.semantic_analyzer.declare_procedure(procedure) Analyzers2.semantic_analyzer.set_scope(procedure) if tk_list[i + 1][1] == "<IDENTIFIER>": res, e = Analyzers2.is_formal_parameters(tk_list, i + 2) if ( res.token == "<FORMAL_PARAMETERS>" and tk_list[res.col[1] + 1][1] == "<COMMAND_END>" ): i = res.col[1] + 1 res, e = Analyzers2.is_bloc(tk_list, i + 1) if res.token == "<BLOC>": # print("procedure declaration bloc") i = res.col[1] token = Token_( tk_list[initial:i], "<PROCEDURE_DECLARATION>", (initial, i) ) Analyzers2.semantic_analyzer.set_scope() return token, errors elif tk_list[i + 1][1] == "<COMMAND_END>": i += 1 res, e = Analyzers2.is_bloc(tk_list, i + 1) if res.token == "<BLOC>": i = res.col[1] + 1 # print("procedure declaration bloc") token = Token_( tk_list[initial:i], "<PROCEDURE_DECLARATION>", (initial, i) ) Analyzers2.semantic_analyzer.procedure_declaration(token) Analyzers2.semantic_analyzer.set_scope() return token, errors return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_therm(cls, tk_list: list) -> Token_: len_tk_list = len(tk_list) if len_tk_list >= 1 and tk_list[0] == "<FACTOR>": i = 1 checked = True while True: if i < len_tk_list: if not (tk_list[i] in [ "<MULTIPLICATION_SIGN>", "<DIVISION_SIGN>", "<KEYWORD_AND>" ] and (i + 1 < len_tk_list and tk_list[i + 1] == "<FACTOR>")): checked = False break else: break i += 2 if checked: return Token_(tk_list, "<THERM>", None) return Token_("", None, None)
def is_expression(tk_list: list, i: int): initial = i errors = [] l = len(tk_list) tk_atual = Convert(tk_list, i) res, e = Analyzers2.is_simple_expression(tk_list, i) if i < l and res.token == "<SIMPLE_EXPRESSION>": i = res.col[1] if i < l and tk_list[i][1] == "<RELATION>": res, e = Analyzers2.is_simple_expression(tk_list, i + 1) if res.token == "<SIMPLE_EXPRESSION>": i = res.col[1] else: return ( Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors, ) return Token_(tk_list[initial:i], "<EXPRESSION>", (initial, i)), errors return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def is_command(tk_list: list, i: int): initial = i errors = [] tk_atual = Convert(tk_list, i) conditions = { "<ASSIGNMENT>": Analyzers2.is_assignment, "<PROCEDURE_CALL>": Analyzers2.is_procedure_call, "<COMPOSITE_COMMAND>": Analyzers2.is_composite_command, "<CONDITIONAL_COMMAND_1>": Analyzers2.is_conditional_command_1, "<REPETITIVE_COMMAND_1>": Analyzers2.is_repetitive_command, } for token_type in conditions: res, e = conditions[token_type](tk_list, i) if res.token == token_type: i = res.col[1] errors.extend(e) if token_type == "<COMPOSITE_COMMAND>": i += 1 return Token_(tk_list[initial:i], "<COMMAND>", (initial, i)), errors return Token_(tk_list[initial : i + 1], "<ERROR>", (initial, i + 1)), errors
def validate_token(self, tk_list: list) -> Token_: # print(tk_list) try: return list( filter( lambda x: x.token != None, [ validator(tk_list) for validator in self.token_validators ], )).pop() except Exception as inst: # print(inst) return Token_("", None, None)