Skip to content

Commit 9862181

Browse files
bpo-41044: Generate valid PEG python parsers for opt+seq rules (GH-20995)
Co-authored-by: Pablo Galindo <[email protected]> (cherry picked from commit 55460ee) Co-authored-by: Batuhan Taskaya <[email protected]>
1 parent c9f83c1 commit 9862181

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

Lib/test/test_peg_generator/test_pegen.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,14 @@ def test_start_leader(self) -> None:
493493
# Would assert False without a special case in compute_left_recursives().
494494
make_parser(grammar)
495495

496+
def test_opt_sequence(self) -> None:
497+
grammar = """
498+
start: [NAME*]
499+
"""
500+
# This case was failing because of a double trailing comma at the end
501+
# of a line in the generated source. See bpo-41044
502+
make_parser(grammar)
503+
496504
def test_left_recursion_too_complex(self) -> None:
497505
grammar = """
498506
start: foo

Tools/peg_generator/pegen/python_generator.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,13 @@ def visit_NegativeLookahead(self, node: NegativeLookahead) -> Tuple[None, str]:
9393

9494
def visit_Opt(self, node: Opt) -> Tuple[str, str]:
9595
name, call = self.visit(node.node)
96-
return "opt", f"{call}," # Note trailing comma!
96+
# Note trailing comma (the call may already have one comma
97+
# at the end, for example when rules have both repeat0 and optional
98+
# markers, e.g: [rule*])
99+
if call.endswith(","):
100+
return "opt", call
101+
else:
102+
return "opt", f"{call},"
97103

98104
def visit_Repeat0(self, node: Repeat0) -> Tuple[str, str]:
99105
if node in self.cache:

0 commit comments

Comments
 (0)