This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 

114 líneas
3.0 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. c = -compare( len(rule1.expansion), len(rule2.expansion))
  9. if rule1.origin.startswith('__'): # XXX hack! We should set priority in parser, not here
  10. c = -c
  11. return c
  12. def _sum_priority(tree):
  13. p = 0
  14. for n in tree.iter_subtrees():
  15. try:
  16. p += n.rule.options.priority or 0
  17. except AttributeError:
  18. pass
  19. return p
  20. def _compare_priority(tree1, tree2):
  21. tree1.iter_subtrees()
  22. def _compare_drv(tree1, tree2):
  23. try:
  24. rule1, rule2 = tree1.rule, tree2.rule
  25. except AttributeError:
  26. # Probably non-trees, or user trees that weren't created by the parse (better way to distinguish?)
  27. return compare(tree1, tree2)
  28. assert tree1.data != '_ambig'
  29. assert tree2.data != '_ambig'
  30. p1 = _sum_priority(tree1)
  31. p2 = _sum_priority(tree2)
  32. c = (p1 or p2) and compare(p1, p2)
  33. if c:
  34. return c
  35. c = _compare_rules(tree1.rule, tree2.rule)
  36. if c:
  37. return c
  38. # rules are "equal", so compare trees
  39. if len(tree1.children) == len(tree2.children):
  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. key_f = cmp_to_key(_compare_drv)
  48. best = max(tree.children, key=key_f)
  49. assert best.data == 'drv'
  50. tree.set('drv', best.children)
  51. tree.rule = best.rule # needed for applying callbacks
  52. def standard_resolve_ambig(tree):
  53. for ambig in tree.find_data('_ambig'):
  54. _standard_resolve_ambig(ambig)
  55. return tree
  56. # Anti-score Sum
  57. #
  58. # Author: Uriva (https://github.com/uriva)
  59. def _antiscore_sum_drv(tree):
  60. if not isinstance(tree, Tree):
  61. return 0
  62. # XXX These artifacts can appear due to imperfections in the ordering of Visitor_NoRecurse,
  63. # when confronted with duplicate (same-id) nodes. Fixing this ordering is possible, but would be
  64. # computationally inefficient. So we handle it here.
  65. if tree.data == '_ambig':
  66. _antiscore_sum_resolve_ambig(tree)
  67. try:
  68. priority = tree.rule.options.priority
  69. except AttributeError:
  70. # Probably trees that don't take part in this parse (better way to distinguish?)
  71. priority = None
  72. return (priority or 0) + sum(map(_antiscore_sum_drv, tree.children), 0)
  73. def _antiscore_sum_resolve_ambig(tree):
  74. assert tree.data == '_ambig'
  75. best = min(tree.children, key=_antiscore_sum_drv)
  76. assert best.data == 'drv'
  77. tree.set('drv', best.children)
  78. tree.rule = best.rule # needed for applying callbacks
  79. def antiscore_sum_resolve_ambig(tree):
  80. for ambig in tree.find_data('_ambig'):
  81. _antiscore_sum_resolve_ambig(ambig)
  82. return tree