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.

81 regels
2.5 KiB

  1. from .common import is_terminal
  2. class Callback(object):
  3. pass
  4. def create_expand1_tree_builder_function(tree_builder):
  5. def f(children):
  6. if len(children) == 1:
  7. return children[0]
  8. else:
  9. return tree_builder(children)
  10. return f
  11. def create_rule_handler(expansion, usermethod):
  12. to_include = [(i, sym.startswith('_')) for i, sym in enumerate(expansion)
  13. if not (is_terminal(sym) and sym.startswith('_'))]
  14. if len(to_include) < len(expansion) or any(to_expand for i, to_expand in to_include):
  15. def _build_ast(match):
  16. children = []
  17. for i, to_expand in to_include:
  18. if to_expand:
  19. children += match[i].children
  20. else:
  21. children.append(match[i])
  22. return usermethod(children)
  23. else:
  24. _build_ast = usermethod
  25. return _build_ast
  26. class ParseTreeBuilder:
  27. def __init__(self, tree_class):
  28. self.tree_class = tree_class
  29. def _create_tree_builder_function(self, name):
  30. tree_class = self.tree_class
  31. def f(children):
  32. return tree_class(name, children)
  33. return f
  34. def create_tree_builder(self, rules, transformer):
  35. callback = Callback()
  36. new_rules = []
  37. for origin, expansions in rules.items():
  38. expand1 = origin.startswith('?')
  39. _origin = origin.lstrip('?*')
  40. for expansion, alias in expansions:
  41. if alias and origin.startswith('_'):
  42. raise Exception("Rule %s is marked for expansion (it starts with an underscore) and isn't allowed to have aliases" % origin)
  43. if alias:
  44. alias = alias.lstrip('*')
  45. _alias = 'autoalias_%s_%s' % (_origin, '_'.join(expansion))
  46. try:
  47. f = transformer._get_func(alias or _origin)
  48. except AttributeError:
  49. if alias:
  50. f = self._create_tree_builder_function(alias)
  51. else:
  52. f = self._create_tree_builder_function(_origin)
  53. if expand1:
  54. f = create_expand1_tree_builder_function(f)
  55. alias_handler = create_rule_handler(expansion, f)
  56. assert not hasattr(callback, _alias)
  57. setattr(callback, _alias, alias_handler)
  58. new_rules.append(( _origin, expansion, _alias ))
  59. return new_rules, callback