One function
AmbiguousExpander in lark-parser/lark
The author described this change as “Fix AmbiguousExpander (Issue #1214)”. It counts as a record because the check below fails on the code as it stood at 7ef5c98d1 and passes on a2f914e01, with nothing else changed between the two runs.
Projectlark-parser/lark
Fix saved2022-11-20
Sharing licenceMIT · LICENSE
Change size+3 −3
What the code was meant to do, written into the code itself as a docstring
Deal with the case where we're expanding children ('_rule') into a parent but the children are ambiguous. i.e. (parent->_ambig->_expand_this_rule). In this case, make the parent itself ambiguous with as many copies as their are ambiguous children, and then copy the ambiguous children into the right parents in the right places, essentially shifting the ambiguity up the tree.
The change
| 1 | 1 | class AmbiguousExpander: | |
| 2 | 2 | """Deal with the case where we're expanding children ('_rule') into a parent but the children | |
| 3 | 3 | are ambiguous. i.e. (parent->_ambig->_expand_this_rule). In this case, make the parent itself | |
| 4 | - | ambiguous with as many copies as their are ambiguous children, and then copy the ambiguous children | |
| 4 | + | ambiguous with as many copies as there are ambiguous children, and then copy the ambiguous children | |
| 5 | 5 | into the right parents in the right places, essentially shifting the ambiguity up the tree.""" | |
| 6 | 6 | def __init__(self, to_expand, tree_class, node_builder): | |
| 7 | 7 | self.node_builder = node_builder | |
| ⋯ | |||
| 27 | 27 | if not ambiguous: | |
| 28 | 28 | return self.node_builder(children) | |
| 29 | 29 | ||
| 30 | - | expand = [iter(child.children) if i in ambiguous else repeat(child) for i, child in enumerate(children)] | |
| 31 | - | return self.tree_class('_ambig', [self.node_builder(list(f[0])) for f in product(zip(*expand))]) | |
| 30 | + | expand = [child.children if i in ambiguous else (child,) for i, child in enumerate(children)] | |
| 31 | + | return self.tree_class('_ambig', [self.node_builder(list(f)) for f in product(*expand)]) | |
The check that tells the two apart
fail→pass·tests/test_parser.py::TestFullEarleyDynamic::test_ambiguous_inlined_rule
Check file tests/test_parser.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.
Origin and history
The code before it7ef5c98d10638dbeaf038aef8bf86cc278a9f45a
Broken version dated2022-11-02
Modulelark.parse_tree_builder
Units changedAmbiguousExpander
Fingerprinte09559ce2bc64e76
Checked2026-08-18 by goldset/0.1
Every field above is generated by our program. None of it is written by hand.
Other bugs found in lark-parser/lark
- 2026-07-08Fix lexer_callbacks silently dropped for keyword terminals
- 2026-06-24Transformer_NonRecursive
- 2026-06-04Raise GrammarError for non-terminal names in %declare
- 2026-06-02Fix empty SPPF node from xearley ignore carry-over (fixes #1598)
- 2026-05-24fix: raise GrammarError for template usage inside terminals
- 2024-10-25Adjust behaviour in #1481 to raise a NotImplementedError