]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-41044: Generate valid PEG python parsers for opt+seq rules (GH-20995)
authorBatuhan Taskaya <isidentical@gmail.com>
Sat, 20 Jun 2020 17:40:06 +0000 (20:40 +0300)
committerGitHub <noreply@github.com>
Sat, 20 Jun 2020 17:40:06 +0000 (18:40 +0100)
Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
Lib/test/test_peg_generator/test_pegen.py
Tools/peg_generator/pegen/python_generator.py

index 30e1b675643b23dcad1e40d7baffb41483433842..5b4e964d698adec6486939b41d1cba922beb1737 100644 (file)
@@ -493,6 +493,14 @@ class TestPegen(unittest.TestCase):
         # Would assert False without a special case in compute_left_recursives().
         make_parser(grammar)
 
+    def test_opt_sequence(self) -> None:
+        grammar = """
+        start: [NAME*]
+        """
+        # This case was failing because of a double trailing comma at the end
+        # of a line in the generated source. See bpo-41044
+        make_parser(grammar)
+
     def test_left_recursion_too_complex(self) -> None:
         grammar = """
         start: foo
index 64336552f24f6cee0944a33da89615588e648893..45a75975dbf5e08a49f1c6b2da317ef7e37d38d1 100644 (file)
@@ -93,7 +93,13 @@ class PythonCallMakerVisitor(GrammarVisitor):
 
     def visit_Opt(self, node: Opt) -> Tuple[str, str]:
         name, call = self.visit(node.node)
-        return "opt", f"{call},"  # Note trailing comma!
+        # Note trailing comma (the call may already have one comma
+        # at the end, for example when rules have both repeat0 and optional
+        # markers, e.g: [rule*])
+        if call.endswith(","):
+            return "opt", call
+        else:
+            return "opt", f"{call},"
 
     def visit_Repeat0(self, node: Repeat0) -> Tuple[str, str]:
         if node in self.cache: