This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

81 righe
2.6 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):
  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 tree_builder_f(children):
  32. return tree_class(name, children)
  33. return tree_builder_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. if hasattr(callback, _alias):
  57. raise GrammarError("Rule expansion '%s' already exists in rule %s" % (' '.join(expansion), origin))
  58. setattr(callback, _alias, alias_handler)
  59. new_rules.append(( _origin, expansion, _alias ))
  60. return new_rules, callback