From 07fcc26422d2cded7562bdfa443e1663e84498e8 Mon Sep 17 00:00:00 2001 From: Erez Shinan Date: Tue, 15 Aug 2017 18:49:26 +0300 Subject: [PATCH] Bugfix #21: Can now handle recursive ambiguity while still defending against infinite recursion --- lark/parsers/earley.py | 12 ++++++++++-- lark/parsers/xearley.py | 6 +++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lark/parsers/earley.py b/lark/parsers/earley.py index 52d23dd..a00bb36 100644 --- a/lark/parsers/earley.py +++ b/lark/parsers/earley.py @@ -56,8 +56,12 @@ class Item(object): new_tree = Derivation(self.rule, self.tree.children + [tree]) return Item(self.rule, self.ptr+1, self.start, new_tree) - def __eq__(self, other): + def similar(self, other): return self.start is other.start and self.ptr == other.ptr and self.rule == other.rule + + def __eq__(self, other): + return self.similar(other) and (self.tree is other.tree or self.tree == other.tree) + def __hash__(self): return hash((self.rule, self.ptr, id(self.start))) @@ -168,7 +172,11 @@ class Parser: for nonterm in to_predict: column.add( predict(nonterm, column) ) for item in to_reduce: - column.add( complete(item) ) + new_items = list(complete(item)) + for new_item in new_items: + if new_item.similar(item): + raise ParseError('Infinite recursion detected! (rule %s)' % new_item.rule) + column.add(new_items) def scan(i, token, column): to_scan = column.to_scan.get_news() diff --git a/lark/parsers/xearley.py b/lark/parsers/xearley.py index ba86c5c..a74852a 100644 --- a/lark/parsers/xearley.py +++ b/lark/parsers/xearley.py @@ -70,7 +70,11 @@ class Parser: for nonterm in to_predict: column.add( predict(nonterm, column) ) for item in to_reduce: - column.add( complete(item) ) + new_items = list(complete(item)) + for new_item in new_items: + if new_item.similar(item): + raise ParseError('Infinite recursion detected! (rule %s)' % new_item.rule) + column.add(new_items) def scan(i, token, column): for x in self.ignore: