This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

84 lines
2.3 KiB

  1. class Tree(object):
  2. def __init__(self, data, children):
  3. self.data = data
  4. self.children = list(children)
  5. def __repr__(self):
  6. return 'Tree(%s, %s)' % (self.data, self.children)
  7. def _pretty(self, level, indent_str):
  8. if len(self.children) == 1 and not isinstance(self.children[0], Tree):
  9. return [ indent_str*level, self.data, '\t', '%s' % self.children[0], '\n']
  10. l = [ indent_str*level, self.data, '\n' ]
  11. for n in self.children:
  12. if isinstance(n, Tree):
  13. l += n._pretty(level+1, indent_str)
  14. else:
  15. l += [ indent_str*(level+1), '%s' % n, '\n' ]
  16. return l
  17. def pretty(self, indent_str=' '):
  18. return ''.join(self._pretty(0, indent_str))
  19. def expand_kids_by_index(self, *indices):
  20. for i in sorted(indices, reverse=True): # reverse so that changing tail won't affect indices
  21. kid = self.children[i]
  22. self.children[i:i+1] = kid.children
  23. # def find_path(self, pred):
  24. # if pred(self):
  25. # yield []
  26. # else:
  27. # for i, c in enumerate(self.children):
  28. # if isinstance(c, Tree):
  29. # for path in c.find_path(pred):
  30. # yield [i] + path
  31. # def follow_path(self, path):
  32. # x = self
  33. # for step in path:
  34. # x = x.children[step]
  35. # return x
  36. # def set_at_path(self, path, value):
  37. # x = self.follow_path(path[:-1])
  38. # x.children[path[-1]] = value
  39. def clone(self):
  40. return Tree(self.data, [c.clone() if isinstance(c, Tree) else c for c in self.children])
  41. class Transformer(object):
  42. def transform(self, tree):
  43. items = [self.transform(c) if isinstance(c, Tree) else c for c in tree.children]
  44. try:
  45. f = getattr(self, tree.data)
  46. except AttributeError:
  47. return self.__default__(tree.data, items)
  48. else:
  49. return f(*items)
  50. def __default__(self, data, children):
  51. return Tree(data, children)
  52. class Visitor(object):
  53. def visit(self, tree):
  54. for child in tree.children:
  55. if isinstance(child, Tree):
  56. self.visit(child)
  57. f = getattr(self, tree.data, self.__default__)
  58. f(tree)
  59. return tree
  60. def __default__(self, tree):
  61. pass