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.

86 lines
2.8 KiB

  1. from .utils import STRING_TYPE
  2. class LarkError(Exception):
  3. pass
  4. class GrammarError(LarkError):
  5. pass
  6. class ParseError(LarkError):
  7. pass
  8. class LexError(LarkError):
  9. pass
  10. class UnexpectedInput(LarkError):
  11. def get_context(self, text, span=10):
  12. pos = self.pos_in_stream
  13. start = max(pos - span, 0)
  14. end = pos + span
  15. before = text[start:pos].rsplit('\n', 1)[-1]
  16. after = text[pos:end].split('\n', 1)[0]
  17. return before + after + '\n' + ' ' * len(before) + '^\n'
  18. def match_examples(self, parse_fn, examples):
  19. """ Given a parser instance and a dictionary mapping some label with
  20. some malformed syntax examples, it'll return the label for the
  21. example that bests matches the current error.
  22. """
  23. assert self.state is not None, "Not supported for this exception"
  24. candidate = None
  25. for label, example in examples.items():
  26. assert not isinstance(example, STRING_TYPE)
  27. for malformed in example:
  28. try:
  29. parse_fn(malformed)
  30. except UnexpectedInput as ut:
  31. if ut.state == self.state:
  32. try:
  33. if ut.token == self.token: # Try exact match first
  34. return label
  35. except AttributeError:
  36. pass
  37. if not candidate:
  38. candidate = label
  39. return candidate
  40. class UnexpectedCharacters(LexError, UnexpectedInput):
  41. def __init__(self, seq, lex_pos, line, column, allowed=None, considered_tokens=None, state=None):
  42. context = seq[lex_pos:lex_pos+10]
  43. message = "No token defined for '%s' in %r at line %d col %d" % (seq[lex_pos], context, line, column)
  44. if allowed:
  45. message += '\n\nExpecting: %s\n' % allowed
  46. super(UnexpectedCharacters, self).__init__(message)
  47. self.line = line
  48. self.column = column
  49. self.context = context
  50. self.allowed = allowed
  51. self.considered_tokens = considered_tokens
  52. self.pos_in_stream = lex_pos
  53. self.state = state
  54. class UnexpectedToken(ParseError, UnexpectedInput):
  55. def __init__(self, token, expected, considered_rules=None, state=None):
  56. self.token = token
  57. self.expected = expected # XXX str shouldn't necessary
  58. self.line = getattr(token, 'line', '?')
  59. self.column = getattr(token, 'column', '?')
  60. self.considered_rules = considered_rules
  61. self.state = state
  62. self.pos_in_stream = token.pos_in_stream
  63. message = ("Unexpected token %r at line %s, column %s.\n"
  64. "Expected: %s\n"
  65. % (token, self.line, self.column, ', '.join(self.expected)))
  66. super(UnexpectedToken, self).__init__(message)