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.

87 righe
2.9 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, sym.startswith('_')) for i, sym in enumerate(expansion)
  14. if not (is_terminal(sym) and sym.startswith('_'))]
  15. if len(to_include) < len(expansion) or any(to_expand for i, to_expand in to_include):
  16. def _build_ast(match):
  17. children = []
  18. for i, to_expand in to_include:
  19. if to_expand:
  20. children += match[i].children
  21. else:
  22. children.append(match[i])
  23. return usermethod(children)
  24. return _build_ast
  25. # else, if no filtering required..
  26. return usermethod
  27. class ParseTreeBuilder:
  28. def __init__(self, tree_class):
  29. self.tree_class = tree_class
  30. def _create_tree_builder_function(self, name):
  31. tree_class = self.tree_class
  32. def tree_builder_f(children):
  33. return tree_class(name, children)
  34. return tree_builder_f
  35. def create_tree_builder(self, rules, transformer):
  36. callback = Callback()
  37. new_rules = []
  38. for origin, expansions in rules.items():
  39. keep_all_tokens = False
  40. if origin.startswith('!'):
  41. origin=origin.lstrip('!')
  42. keep_all_tokens = True
  43. expand1 = origin.startswith('?')
  44. _origin = origin.lstrip('?')
  45. for expansion, alias in expansions:
  46. if alias and origin.startswith('_'):
  47. raise Exception("Rule %s is marked for expansion (it starts with an underscore) and isn't allowed to have aliases" % origin)
  48. if alias:
  49. alias = alias.lstrip('*')
  50. _alias = 'autoalias_%s_%s' % (_origin, '_'.join(expansion))
  51. try:
  52. f = transformer._get_func(alias or _origin)
  53. except AttributeError:
  54. if alias:
  55. f = self._create_tree_builder_function(alias)
  56. else:
  57. f = self._create_tree_builder_function(_origin)
  58. if expand1:
  59. f = create_expand1_tree_builder_function(f)
  60. alias_handler = create_rule_handler(expansion, f, keep_all_tokens)
  61. if hasattr(callback, _alias):
  62. raise GrammarError("Rule expansion '%s' already exists in rule %s" % (' '.join(expansion), origin))
  63. setattr(callback, _alias, alias_handler)
  64. new_rules.append(( _origin, expansion, _alias ))
  65. return new_rules, callback