This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 

110 řádky
3.4 KiB

  1. from ..utils import compare
  2. from functools import cmp_to_key
  3. from ..tree import Tree, Visitor_NoRecurse
  4. # Standard ambiguity resolver (uses comparison)
  5. #
  6. # Author: Erez Sh
  7. def _compare_rules(rule1, rule2):
  8. if rule1.origin != rule2.origin:
  9. if rule1.options and rule2.options:
  10. if rule1.options.priority is not None and rule2.options.priority is not None:
  11. assert rule1.options.priority != rule2.options.priority, "Priority is the same between both rules: %s == %s" % (rule1, rule2)
  12. return -compare(rule1.options.priority, rule2.options.priority)
  13. return 0
  14. c = compare( len(rule1.expansion), len(rule2.expansion))
  15. if rule1.origin.startswith('__'): # XXX hack! We need to set priority in parser, not here
  16. c = -c
  17. return c
  18. def _compare_drv(tree1, tree2):
  19. if not (isinstance(tree1, Tree) and isinstance(tree2, Tree)):
  20. try:
  21. return -compare(tree1, tree2)
  22. except TypeError:
  23. return 0
  24. try:
  25. rule1, rule2 = tree1.rule, tree2.rule
  26. except AttributeError:
  27. # Probably trees that don't take part in this parse (better way to distinguish?)
  28. return -compare(tree1, tree2)
  29. # XXX These artifacts can appear due to imperfections in the ordering of Visitor_NoRecurse,
  30. # when confronted with duplicate (same-id) nodes. Fixing this ordering is possible, but would be
  31. # computationally inefficient. So we handle it here.
  32. if tree1.data == '_ambig':
  33. _standard_resolve_ambig(tree1)
  34. if tree2.data == '_ambig':
  35. _standard_resolve_ambig(tree2)
  36. c = _compare_rules(tree1.rule, tree2.rule)
  37. if c:
  38. return c
  39. # rules are "equal", so compare trees
  40. for t1, t2 in zip(tree1.children, tree2.children):
  41. c = _compare_drv(t1, t2)
  42. if c:
  43. return c
  44. return compare(len(tree1.children), len(tree2.children))
  45. def _standard_resolve_ambig(tree):
  46. assert tree.data == '_ambig'
  47. best = min(tree.children, key=cmp_to_key(_compare_drv))
  48. assert best.data == 'drv'
  49. tree.set('drv', best.children)
  50. tree.rule = best.rule # needed for applying callbacks
  51. def standard_resolve_ambig(tree):
  52. for ambig in tree.find_data('_ambig'):
  53. _standard_resolve_ambig(ambig)
  54. return tree
  55. # Anti-score Sum
  56. #
  57. # Author: Uriva (https://github.com/uriva)
  58. def _antiscore_sum_drv(tree):
  59. if not isinstance(tree, Tree):
  60. return 0
  61. # XXX These artifacts can appear due to imperfections in the ordering of Visitor_NoRecurse,
  62. # when confronted with duplicate (same-id) nodes. Fixing this ordering is possible, but would be
  63. # computationally inefficient. So we handle it here.
  64. if tree.data == '_ambig':
  65. _antiscore_sum_resolve_ambig(tree)
  66. try:
  67. priority = tree.rule.options.priority
  68. except AttributeError:
  69. # Probably trees that don't take part in this parse (better way to distinguish?)
  70. priority = None
  71. return (priority or 0) + sum(map(_antiscore_sum_drv, tree.children), 0)
  72. def _antiscore_sum_resolve_ambig(tree):
  73. assert tree.data == '_ambig'
  74. best = min(tree.children, key=_antiscore_sum_drv)
  75. assert best.data == 'drv'
  76. tree.set('drv', best.children)
  77. tree.rule = best.rule # needed for applying callbacks
  78. def antiscore_sum_resolve_ambig(tree):
  79. for ambig in tree.find_data('_ambig'):
  80. _antiscore_sum_resolve_ambig(ambig)
  81. return tree