This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

83 wiersze
2.8 KiB

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