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.

117 lines
3.2 KiB

  1. class Symbol(object):
  2. is_term = NotImplemented
  3. def __init__(self, name):
  4. self.name = name
  5. def __eq__(self, other):
  6. assert isinstance(other, Symbol), other
  7. return self.is_term == other.is_term and self.name == other.name
  8. def __ne__(self, other):
  9. return not (self == other)
  10. def __hash__(self):
  11. return hash(self.name)
  12. def __repr__(self):
  13. return '%s(%r)' % (type(self).__name__, self.name)
  14. fullrepr = property(__repr__)
  15. @classmethod
  16. def deserialize(cls, data):
  17. class_ = {
  18. 'T': Terminal,
  19. 'NT': NonTerminal,
  20. }[data[0]]
  21. return class_(*data[1:])
  22. class Terminal(Symbol):
  23. is_term = True
  24. def __init__(self, name, filter_out=False):
  25. self.name = name
  26. self.filter_out = filter_out
  27. @property
  28. def fullrepr(self):
  29. return '%s(%r, %r)' % (type(self).__name__, self.name, self.filter_out)
  30. def serialize(self):
  31. return ['T', self.name, self.filter_out]
  32. class NonTerminal(Symbol):
  33. is_term = False
  34. def serialize(self):
  35. return ['NT', self.name]
  36. class Rule(object):
  37. """
  38. origin : a symbol
  39. expansion : a list of symbols
  40. order : index of this expansion amongst all rules of the same name
  41. """
  42. __slots__ = ('origin', 'expansion', 'alias', 'options', 'order', '_hash')
  43. def __init__(self, origin, expansion, order=0, alias=None, options=None):
  44. self.origin = origin
  45. self.expansion = expansion
  46. self.alias = alias
  47. self.order = order
  48. self.options = options
  49. self._hash = hash((self.origin, tuple(self.expansion)))
  50. def __str__(self):
  51. return '<%s : %s>' % (self.origin.name, ' '.join(x.name for x in self.expansion))
  52. def __repr__(self):
  53. return 'Rule(%r, %r, %r, %r)' % (self.origin, self.expansion, self.alias, self.options)
  54. def __hash__(self):
  55. return self._hash
  56. def __eq__(self, other):
  57. if not isinstance(other, Rule):
  58. return False
  59. return self.origin == other.origin and self.expansion == other.expansion
  60. def serialize(self):
  61. return [self.origin.serialize(), list(s.serialize() for s in self.expansion), self.order, self.alias, self.options.serialize() if self.options else None]
  62. @classmethod
  63. def deserialize(cls, data):
  64. origin, expansion, order, alias, options = data
  65. return cls(
  66. Symbol.deserialize(origin),
  67. [Symbol.deserialize(s) for s in expansion],
  68. order,
  69. alias,
  70. RuleOptions.deserialize(options) if options else None
  71. )
  72. class RuleOptions:
  73. def __init__(self, keep_all_tokens=False, expand1=False, priority=None, empty_indices=()):
  74. self.keep_all_tokens = keep_all_tokens
  75. self.expand1 = expand1
  76. self.priority = priority
  77. self.empty_indices = empty_indices
  78. def __repr__(self):
  79. return 'RuleOptions(%r, %r, %r)' % (
  80. self.keep_all_tokens,
  81. self.expand1,
  82. self.priority,
  83. )
  84. def serialize(self):
  85. return [self.keep_all_tokens, self.expand1, self.priority, list(self.empty_indices)]
  86. @classmethod
  87. def deserialize(cls, data):
  88. return cls(*data)