Browse Source

Implemented a new visitor class (Interpreter) that works top-down (PR #130)

It emulates antlr's visitor behavior for a dynamic evaluation order of subtrees
tags/gm/2021-09-23T00Z/github.com--lark-parser-lark/0.6.0
Ramon Klass 6 years ago
committed by Erez Shinan
parent
commit
f5550b3040
2 changed files with 56 additions and 1 deletions
  1. +24
    -0
      lark/tree.py
  2. +32
    -1
      tests/test_trees.py

+ 24
- 0
lark/tree.py View File

@@ -174,6 +174,30 @@ class Visitor_NoRecurse(Visitor):
return tree


from functools import wraps
def visit_children_decor(func):
@wraps(func)
def inner(cls, tree):
values = cls.visit_children(tree)
return func(cls, values)
return inner

class Interpreter(object):

def visit(self, tree):
return getattr(self, tree.data)(tree)

def visit_children(self, tree):
return [self.visit(child) if isinstance(child, Tree) else child
for child in tree.children]

def __getattr__(self, name):
return self.__default__

def __default__(self, tree):
self.visit_children(tree)


class Transformer_NoRecurse(Transformer):
def transform(self, tree):
subtrees = list(tree.iter_subtrees())


+ 32
- 1
tests/test_trees.py View File

@@ -5,7 +5,7 @@ from unittest import TestCase
import copy
import pickle

from lark.tree import Tree
from lark.tree import Tree, Interpreter, visit_children_decor


class TestTrees(TestCase):
@@ -21,6 +21,37 @@ class TestTrees(TestCase):
assert pickle.loads(data) == s


def test_interp(self):
t = Tree('a', [Tree('b', []), Tree('c', []), 'd'])

class Interp1(Interpreter):
def a(self, tree):
return self.visit_children(tree) + ['e']

def b(self, tree):
return 'B'

def c(self, tree):
return 'C'

self.assertEqual(Interp1().visit(t), list('BCde'))

class Interp2(Interpreter):
@visit_children_decor
def a(self, values):
return values + ['e']

def b(self, tree):
return 'B'

def c(self, tree):
return 'C'

self.assertEqual(Interp2().visit(t), list('BCde'))




if __name__ == '__main__':
unittest.main()


Loading…
Cancel
Save