|
- from utils import inline_args
-
- class Tree(object):
- def __init__(self, data, children):
- self.data = data
- self.children = list(children)
-
- def __repr__(self):
- return 'Tree(%s, %s)' % (self.data, self.children)
-
- def _pretty(self, level, indent_str):
- if len(self.children) == 1 and not isinstance(self.children[0], Tree):
- return [ indent_str*level, self.data, '\t', '%s' % self.children[0], '\n']
-
- l = [ indent_str*level, self.data, '\n' ]
- for n in self.children:
- if isinstance(n, Tree):
- l += n._pretty(level+1, indent_str)
- else:
- l += [ indent_str*(level+1), '%s' % n, '\n' ]
-
- return l
-
- def pretty(self, indent_str=' '):
- return ''.join(self._pretty(0, indent_str))
-
- def expand_kids_by_index(self, *indices):
- for i in sorted(indices, reverse=True): # reverse so that changing tail won't affect indices
- kid = self.children[i]
- self.children[i:i+1] = kid.children
-
-
- # def find_path(self, pred):
- # if pred(self):
- # yield []
- # else:
- # for i, c in enumerate(self.children):
- # if isinstance(c, Tree):
- # for path in c.find_path(pred):
- # yield [i] + path
-
- # def follow_path(self, path):
- # x = self
- # for step in path:
- # x = x.children[step]
- # return x
-
- # def set_at_path(self, path, value):
- # x = self.follow_path(path[:-1])
- # x.children[path[-1]] = value
-
- def clone(self):
- return Tree(self.data, [c.clone() if isinstance(c, Tree) else c for c in self.children])
-
-
- class Transformer(object):
- def _get_func(self, name):
- return getattr(self, name)
-
- def transform(self, tree):
- items = [self.transform(c) if isinstance(c, Tree) else c for c in tree.children]
- try:
- f = self._get_func(tree.data)
- except AttributeError:
- return self.__default__(tree.data, items)
- else:
- return f(items)
-
-
- def __default__(self, data, children):
- return Tree(data, children)
-
-
- class InlineTransformer(Transformer):
- def _get_func(self, name):
- return inline_args(getattr(self, name)).__get__(self)
-
-
-
- class Visitor(object):
- def visit(self, tree):
- for child in tree.children:
- if isinstance(child, Tree):
- self.visit(child)
-
- f = getattr(self, tree.data, self.__default__)
- f(tree)
- return tree
-
- def __default__(self, tree):
- pass
-
|