This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
2.4 KiB

  1. from ..utils import compare
  2. from functools import cmp_to_key
  3. from ..tree import Tree
  4. # Standard ambiguity resolver (uses comparison)
  5. #
  6. # Author: Erez Sh
  7. def _compare_rules(rule1, rule2):
  8. return -compare( len(rule1.expansion), len(rule2.expansion))
  9. def _sum_priority(tree):
  10. p = 0
  11. for n in tree.iter_subtrees():
  12. try:
  13. p += n.meta.rule.options.priority or 0
  14. except AttributeError:
  15. pass
  16. return p
  17. def _compare_priority(tree1, tree2):
  18. tree1.iter_subtrees()
  19. def _compare_drv(tree1, tree2):
  20. try:
  21. rule1 = tree1.meta.rule
  22. except AttributeError:
  23. rule1 = None
  24. try:
  25. rule2 = tree2.meta.rule
  26. except AttributeError:
  27. rule2 = None
  28. if None == rule1 == rule2:
  29. return compare(tree1, tree2)
  30. elif rule1 is None:
  31. return -1
  32. elif rule2 is None:
  33. return 1
  34. assert tree1.data != '_ambig'
  35. assert tree2.data != '_ambig'
  36. p1 = _sum_priority(tree1)
  37. p2 = _sum_priority(tree2)
  38. c = (p1 or p2) and compare(p1, p2)
  39. if c:
  40. return c
  41. c = _compare_rules(tree1.meta.rule, tree2.meta.rule)
  42. if c:
  43. return c
  44. # rules are "equal", so compare trees
  45. if len(tree1.children) == len(tree2.children):
  46. for t1, t2 in zip(tree1.children, tree2.children):
  47. c = _compare_drv(t1, t2)
  48. if c:
  49. return c
  50. return compare(len(tree1.children), len(tree2.children))
  51. def _standard_resolve_ambig(tree):
  52. assert tree.data == '_ambig'
  53. key_f = cmp_to_key(_compare_drv)
  54. best = max(tree.children, key=key_f)
  55. assert best.data == 'drv'
  56. tree.set('drv', best.children)
  57. tree.meta.rule = best.meta.rule # needed for applying callbacks
  58. def standard_resolve_ambig(tree):
  59. for ambig in tree.find_data('_ambig'):
  60. _standard_resolve_ambig(ambig)
  61. return tree
  62. # Anti-score Sum
  63. #
  64. # Author: Uriva (https://github.com/uriva)
  65. def _antiscore_sum_drv(tree):
  66. if not isinstance(tree, Tree):
  67. return 0
  68. assert tree.data != '_ambig'
  69. return _sum_priority(tree)
  70. def _antiscore_sum_resolve_ambig(tree):
  71. assert tree.data == '_ambig'
  72. best = min(tree.children, key=_antiscore_sum_drv)
  73. assert best.data == 'drv'
  74. tree.set('drv', best.children)
  75. tree.meta.rule = best.meta.rule # needed for applying callbacks
  76. def antiscore_sum_resolve_ambig(tree):
  77. for ambig in tree.find_data('_ambig'):
  78. _antiscore_sum_resolve_ambig(ambig)
  79. return tree