This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

125 行
3.2 KiB

  1. import re
  2. import sre_parse
  3. class GrammarError(Exception):
  4. pass
  5. class ParseError(Exception):
  6. pass
  7. class UnexpectedToken(ParseError):
  8. def __init__(self, token, expected, seq, index):
  9. self.token = token
  10. self.expected = expected
  11. self.line = getattr(token, 'line', '?')
  12. self.column = getattr(token, 'column', '?')
  13. try:
  14. context = ' '.join(['%r(%s)' % (t.value, t.type) for t in seq[index:index+5]])
  15. except AttributeError:
  16. context = seq[index:index+5]
  17. except TypeError:
  18. context = "<no context>"
  19. message = ("Unexpected token %r at line %s, column %s.\n"
  20. "Expected: %s\n"
  21. "Context: %s" % (token, self.line, self.column, expected, context))
  22. super(UnexpectedToken, self).__init__(message)
  23. def is_terminal(sym):
  24. return isinstance(sym, Terminal) or sym.isupper() or sym[0] == '$'
  25. class LexerConf:
  26. def __init__(self, tokens, ignore=(), postlex=None):
  27. self.tokens = tokens
  28. self.ignore = ignore
  29. self.postlex = postlex
  30. class ParserConf:
  31. def __init__(self, rules, callback, start):
  32. assert all(len(r) == 4 for r in rules)
  33. self.rules = rules
  34. self.callback = callback
  35. self.start = start
  36. class Pattern(object):
  37. def __init__(self, value, flags=None):
  38. self.value = value
  39. self.flags = flags
  40. def __repr__(self):
  41. return repr(self._get_flags() + self.value)
  42. # Pattern Hashing assumes all subclasses have a different priority!
  43. def __hash__(self):
  44. return hash((type(self), self.value))
  45. def __eq__(self, other):
  46. return type(self) == type(other) and self.value == other.value
  47. def _get_flags(self):
  48. if self.flags:
  49. assert len(self.flags) == 1
  50. return '(?%s)' % self.flags
  51. return ''
  52. class PatternStr(Pattern):
  53. def to_regexp(self):
  54. return self._get_flags() + re.escape(self.value)
  55. @property
  56. def min_width(self):
  57. return len(self.value)
  58. max_width = min_width
  59. class PatternRE(Pattern):
  60. def to_regexp(self):
  61. return self._get_flags() + self.value
  62. @property
  63. def min_width(self):
  64. return sre_parse.parse(self.to_regexp()).getwidth()[0]
  65. @property
  66. def max_width(self):
  67. return sre_parse.parse(self.to_regexp()).getwidth()[1]
  68. class TokenDef(object):
  69. def __init__(self, name, pattern, priority=1):
  70. assert isinstance(pattern, Pattern), pattern
  71. self.name = name
  72. self.pattern = pattern
  73. self.priority = priority
  74. def __repr__(self):
  75. return '%s(%r, %r)' % (type(self).__name__, self.name, self.pattern)
  76. class Terminal:
  77. def __init__(self, data):
  78. self.data = data
  79. def __repr__(self):
  80. return '%r' % self.data
  81. def __eq__(self, other):
  82. return isinstance(other, type(self)) and self.data == other.data
  83. def __hash__(self):
  84. return hash(self.data)
  85. class Terminal_Regexp(Terminal):
  86. def __init__(self, name, regexp):
  87. Terminal.__init__(self, regexp)
  88. self.name = name
  89. self.match = re.compile(regexp).match
  90. class Terminal_Token(Terminal):
  91. def match(self, other):
  92. return self.data == other.type