This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

114 行
2.9 KiB

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