Skip to content

Commit

Permalink
Fixed a deep bug in grammar analysis involving empty rules (Issue #250)
Browse files Browse the repository at this point in the history
  • Loading branch information
erezsh committed Oct 15, 2018
1 parent 4a51ebc commit 6c8ba76
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 2 deletions.
3 changes: 2 additions & 1 deletion lark/parsers/cyk.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ def __init__(self, grammar):
for r in self.rules:
# Validate that the grammar is CNF and populate auxiliary data structures.
assert isinstance(r.lhs, NT), r
assert len(r.rhs) in [1, 2], r
if len(r.rhs) not in [1, 2]:
raise ParseError("CYK doesn't support empty rules")
if len(r.rhs) == 1 and isinstance(r.rhs[0], T):
self.terminal_rules[r.rhs[0]].append(r)
elif len(r.rhs) == 2 and all(isinstance(x, NT) for x in r.rhs):
Expand Down
2 changes: 1 addition & 1 deletion lark/parsers/grammar_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def calculate_sets(rules):

for rule in rules:
for i, sym in enumerate(rule.expansion):
if i==len(rule.expansion)-1 or set(rule.expansion[i:]) <= NULLABLE:
if i==len(rule.expansion)-1 or set(rule.expansion[i+1:]) <= NULLABLE:
if update_set(FOLLOW[sym], FOLLOW[rule.origin]):
changed = True

Expand Down
11 changes: 11 additions & 0 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,17 @@ def test_line_counting(self):
self.assertEqual(tok.end_line, 2)
self.assertEqual(tok.end_column, 6)

@unittest.skipIf(PARSER=='cyk', "Empty rules")
def test_empty_end(self):
p = _Lark("""
start: b c d
b: "B"
c: | "C"
d: | "D"
""")
res = p.parse('B')
self.assertEqual(len(res.children), 3)



_NAME = "Test" + PARSER.capitalize() + LEXER.capitalize()
Expand Down

0 comments on commit 6c8ba76

Please sign in to comment.