From cb18cf5e7785dc2dbbcedefb252f18976301d5f3 Mon Sep 17 00:00:00 2001 From: Erez Shinan Date: Sun, 10 Dec 2017 17:54:12 +0200 Subject: [PATCH] BUGFIX: iter_trees() wasn't consistent with a recursive order (Issue #47) --- lark/tree.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lark/tree.py b/lark/tree.py index 90583db..24d24ba 100644 --- a/lark/tree.py +++ b/lark/tree.py @@ -67,17 +67,26 @@ class Tree(object): yield c def iter_subtrees(self): + # TODO: Re-write as a more efficient version + visited = set() q = [self] + l = [] while q: subtree = q.pop() + l.append( subtree ) if id(subtree) in visited: continue # already been here from another branch visited.add(id(subtree)) - yield subtree q += [c for c in subtree.children if isinstance(c, Tree)] + seen = set() + for x in reversed(l): + if id(x) not in seen: + yield x + seen.add(id(x)) + def __deepcopy__(self, memo): return type(self)(self.data, deepcopy(self.children, memo)) @@ -147,7 +156,7 @@ class Visitor_NoRecurse(Visitor): def visit(self, tree): subtrees = list(tree.iter_subtrees()) - for subtree in reversed(subtrees): + for subtree in (subtrees): getattr(self, subtree.data, self.__default__)(subtree) return tree @@ -165,7 +174,7 @@ class Transformer_NoRecurse(Transformer): else: return f(t) - for subtree in reversed(subtrees): + for subtree in (subtrees): subtree.children = [_t(c) if isinstance(c, Tree) else c for c in subtree.children] return _t(tree)