This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
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