This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

110 linhas
2.9 KiB

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