def test_build_parametrised_label(self): built_phrase = phrase_builder(self.expression_context, PhraseClass.label, [Token(TokenClass.word, "label"), Token(TokenClass.parameter, "@")], 0) expected_expr = Phrase(PhraseClass.label, phrase_subclass=None, keyword=Token(TokenClass.word, "label"), params=[Token(TokenClass.parameter, "@")]) self.assertTrue(are_phrases_equal(built_phrase, expected_expr))
def test_build_empty_operator(self): built_phrase = phrase_builder(self.expression_context, PhraseClass.operator, [ Token(TokenClass.word, "delay") ], 0) expected_expr = Phrase(PhraseClass.operator, phrase_subclass=None, keyword=Token(TokenClass.word, "delay"), params=[]) self.assertTrue(are_phrases_equal(built_phrase, expected_expr))
def test_build_comment(self): built_phrase = phrase_builder(self.body_context, PhraseClass.comment, [Token(TokenClass.word, "w1"), Token(TokenClass.word, "w2"), Token(TokenClass.word, "w3")], 0) expected_expr = Phrase(PhraseClass.comment, phrase_subclass=None, params=[Token(TokenClass.word, "w1"), Token(TokenClass.word, "w2"), Token(TokenClass.word, "w3")]) self.assertTrue(are_phrases_equal(built_phrase, expected_expr))
def test_build_operator_with_parameters(self): built_phrase = phrase_builder(self.expression_context, PhraseClass.operator, [ Token(TokenClass.word, "delay"), Token(TokenClass.num, "1"), Token(TokenClass.word, "two"), Token(TokenClass.string, "\"3\""), Token(TokenClass.parameter, "@4") ], 0) expected_expr = Phrase(PhraseClass.operator, phrase_subclass=None, keyword=Token(TokenClass.word, "delay"), params=[Token(TokenClass.num, "1"), Token(TokenClass.word, "two"), Token(TokenClass.string, "\"3\""), Token(TokenClass.parameter, "@4")]) self.assertTrue(are_phrases_equal(built_phrase, expected_expr))
def process_tokens(tree: ParseTree, table: SymbolTable, lang_dict: LangDict, tokens: List[Token]): active_machines: bool = False machine_found: bool = False token_index: int = 0 phrase_start_line: int = 1 temp_phrase: List[Token] = [] sem_analyzer = SemanticAnalyzer(tree, table, lang_dict) while token_index < len(tokens): token: Token = tokens[token_index] # New line check if token.token_class == TokenClass.newline: sem_analyzer.add_line() # Process token with parser machines for machine in machines: machine.process_object(token) if machine.state != State.undefined: active_machines = True # If all machines reach undefined state if not active_machines: # Trying to find machine that recognized phrase for machine in machines: if not machine_found and machine.is_sequence_recognized(): recognized_phrase = phrase_builder(tree.get_context(), machine.name, temp_phrase, phrase_start_line) sem_analyzer.process_phrase(recognized_phrase, phrase_start_line) machine_found = True temp_phrase.clear() # Token wasn't recognized by any machine if not machine_found: for machine in machines: if machine.prevState != State.undefined: raise InterpretationError( PeaceError( f"Unexpected token {repr(token.value)}, expected {machine.name.name}.", ErrorType.syntax_error, sem_analyzer.get_line(), token.value)) # Reset machine states for machine in machines: machine.reset_state() # Get new phrase start line phrase_start_line = sem_analyzer.get_line() # If current token newline - decrease line counter if token.token_class == TokenClass.newline: sem_analyzer.remove_line() # Roll back for 1 token, that led to undefined state (and is an part of next phrase) token_index = token_index - 1 machine_found = False else: # If token belong to some phrase add it to temp phrase if (token.token_class != TokenClass.space and token.token_class != TokenClass.newline and token.token_class != TokenClass.undefined and token.token_class != TokenClass.sign): temp_phrase.append(token) token_index += 1 active_machines = False # Recognize final phrase for machine in machines: machine.process_object(Token(TokenClass.undefined, "")) if not machine_found and machine.is_sequence_recognized(): recognized_phrase = phrase_builder(tree.get_context(), machine.name, temp_phrase, phrase_start_line) sem_analyzer.process_phrase(recognized_phrase, phrase_start_line) machine_found = True if not sem_analyzer.composer.is_tree_valid(): raise InterpretationError( PeaceError("Missing '}}'.", ErrorType.syntax_error, phrase_start_line)) return
def test_build_device_in_body(self): built_phrase = phrase_builder(self.body_context, PhraseClass.block, [Token(TokenClass.word, "device_in_body")], 0) expected_expr = Phrase(PhraseClass.block, PhraseSubclass.device, keyword=Token(TokenClass.word, "device_in_body")) self.assertTrue(are_phrases_equal(built_phrase, expected_expr))
def test_build_expression(self): built_phrase = phrase_builder(self.program_context, PhraseClass.block, [Token(TokenClass.word, "expression")], 0) expected_expr = Phrase(PhraseClass.block, PhraseSubclass.expression, keyword=Token(TokenClass.word, "expression")) self.assertTrue(are_phrases_equal(built_phrase, expected_expr))
def test_build_block_close(self): built_phrase = phrase_builder(self.program_context, PhraseClass.blockClose, [], 0) expected_expr = Phrase(PhraseClass.blockClose, phrase_subclass=None, keyword=None, params=None) self.assertTrue(are_phrases_equal(built_phrase, expected_expr))