From 19ad330dc66f913f31a73f6bab7e4cb064758d14 Mon Sep 17 00:00:00 2001 From: boryanagoncharenko <3010723+boryanagoncharenko@users.noreply.github.com> Date: Wed, 29 May 2024 11:26:45 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=AA=B2=20Broken=20boolean=20translation?= =?UTF-8?q?=20=20(#5574)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #5572 Fixes tests failing due to boolean translation **How to test** 1. Ensure that tests are failing: checkout the **main** branch, comment out the code in snippet_already_tested_with_current_hedy_version and make it always return False, run the tests test_level_15.py and note that tests are failing. 2. To check that the error are fixed: checkout the boolean_translation_5572 branch, again make the snippet_already_tested_with_current_hedy_version always return False and run all tests, ensure that they are all successful. --- hedy_translation.py | 29 +++++++++++++++++++---------- tests/test_level/test_level_03.py | 1 - 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/hedy_translation.py b/hedy_translation.py index 6cf3880d409..2c619a0a0a8 100644 --- a/hedy_translation.py +++ b/hedy_translation.py @@ -1,5 +1,5 @@ from collections import namedtuple -from lark import Token, Visitor +from lark import Token, Transformer, v_args from lark.exceptions import VisitError import hedy import operator @@ -97,7 +97,7 @@ def translate_keywords(input_string, from_lang="en", to_lang="nl", level=1): program_root = parser.parse(processed_input + "\n").children[0] translator = Translator(processed_input) - translator.visit(program_root) + translator.transform(program_root) ordered_rules = reversed(sorted(translator.rules, key=operator.attrgetter("line", "start"))) # checks whether any error production nodes are present in the parse tree @@ -161,7 +161,7 @@ def find_command_keywords( program_root = parser.parse(input_string).children[0] translator = Translator(input_string) - translator.visit(program_root) + translator.transform(program_root) return { k: find_keyword_in_rules( @@ -189,12 +189,15 @@ def get_original_keyword(keyword_dict, keyword, line): return keyword -class Translator(Visitor): - """The visitor finds tokens that must be translated and stores information about their exact position +@v_args(tree=True) +class Translator(Transformer): + """The translator finds tokens that must be translated and stores information about their exact position in the user input string and original value. The information is later used to replace the token in - the original user input with the translated token value.""" + the original user input with the translated token value. Please note that it is a transformer + instead of a visitor because we need tokens to be visited too.""" def __init__(self, input_string): + super().__init__() self.input_string = input_string self.rules = [] @@ -277,6 +280,16 @@ def red(self, tree): def clear(self, tree): self.add_rule_for_grammar_rule("clear", tree) + def TRUE(self, token): + name = 'True' if token and token[0].isupper() else 'true' + rule = Rule(name, token.line, token.column - 1, token.end_column - 2, token) + self.rules.append(rule) + + def FALSE(self, token): + name = 'False' if token and token[0].isupper() else 'false' + rule = Rule(name, token.line, token.column - 1, token.end_column - 2, token) + self.rules.append(rule) + def assign_list(self, tree): self.add_rule_for_grammar_token("_IS", "is", tree) commas = self.get_keyword_tokens("_COMMA", tree) @@ -355,10 +368,6 @@ def for_loop(self, tree): self.add_rule_for_grammar_token("_RANGE", "range", tree) self.add_rule_for_grammar_token("_TO", "to", tree) - def boolean(self, tree): - self.add_rule('TRUE', "true", tree) - self.add_rule('FALSE', "false", tree) - def while_loop(self, tree): self.add_rule_for_grammar_token("_WHILE", "while", tree) diff --git a/tests/test_level/test_level_03.py b/tests/test_level/test_level_03.py index ff965e49b52..30dd879a130 100644 --- a/tests/test_level/test_level_03.py +++ b/tests/test_level/test_level_03.py @@ -90,7 +90,6 @@ def test_color_basic(self): self.single_level_tester( code=code, - translate=False, expected=expected )