Errors.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. # Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
  2. # Use of this file is governed by the BSD 3-clause license that
  3. # can be found in the LICENSE.txt file in the project root.
  4. #
  5. # need forward declaration
  6. Token = None
  7. Lexer = None
  8. Parser = None
  9. TokenStream = None
  10. ATNConfigSet = None
  11. ParserRulecontext = None
  12. PredicateTransition = None
  13. BufferedTokenStream = None
  14. class UnsupportedOperationException(Exception):
  15. def __init__(self, msg:str):
  16. super().__init__(msg)
  17. class IllegalStateException(Exception):
  18. def __init__(self, msg:str):
  19. super().__init__(msg)
  20. class CancellationException(IllegalStateException):
  21. def __init__(self, msg:str):
  22. super().__init__(msg)
  23. # The root of the ANTLR exception hierarchy. In general, ANTLR tracks just
  24. # 3 kinds of errors: prediction errors, failed predicate errors, and
  25. # mismatched input errors. In each case, the parser knows where it is
  26. # in the input, where it is in the ATN, the rule invocation stack,
  27. # and what kind of problem occurred.
  28. from antlr4.InputStream import InputStream
  29. from antlr4.ParserRuleContext import ParserRuleContext
  30. from antlr4.Recognizer import Recognizer
  31. class RecognitionException(Exception):
  32. def __init__(self, message:str=None, recognizer:Recognizer=None, input:InputStream=None, ctx:ParserRulecontext=None):
  33. super().__init__(message)
  34. self.message = message
  35. self.recognizer = recognizer
  36. self.input = input
  37. self.ctx = ctx
  38. # The current {@link Token} when an error occurred. Since not all streams
  39. # support accessing symbols by index, we have to track the {@link Token}
  40. # instance itself.
  41. self.offendingToken = None
  42. # Get the ATN state number the parser was in at the time the error
  43. # occurred. For {@link NoViableAltException} and
  44. # {@link LexerNoViableAltException} exceptions, this is the
  45. # {@link DecisionState} number. For others, it is the state whose outgoing
  46. # edge we couldn't match.
  47. self.offendingState = -1
  48. if recognizer is not None:
  49. self.offendingState = recognizer.state
  50. # <p>If the state number is not known, this method returns -1.</p>
  51. #
  52. # Gets the set of input symbols which could potentially follow the
  53. # previously matched symbol at the time this exception was thrown.
  54. #
  55. # <p>If the set of expected tokens is not known and could not be computed,
  56. # this method returns {@code null}.</p>
  57. #
  58. # @return The set of token types that could potentially follow the current
  59. # state in the ATN, or {@code null} if the information is not available.
  60. #/
  61. def getExpectedTokens(self):
  62. if self.recognizer is not None:
  63. return self.recognizer.atn.getExpectedTokens(self.offendingState, self.ctx)
  64. else:
  65. return None
  66. class LexerNoViableAltException(RecognitionException):
  67. def __init__(self, lexer:Lexer, input:InputStream, startIndex:int, deadEndConfigs:ATNConfigSet):
  68. super().__init__(message=None, recognizer=lexer, input=input, ctx=None)
  69. self.startIndex = startIndex
  70. self.deadEndConfigs = deadEndConfigs
  71. def __str__(self):
  72. symbol = ""
  73. if self.startIndex >= 0 and self.startIndex < self.input.size:
  74. symbol = self.input.getText(self.startIndex, self.startIndex)
  75. # TODO symbol = Utils.escapeWhitespace(symbol, false);
  76. return "LexerNoViableAltException('" + symbol + "')"
  77. # Indicates that the parser could not decide which of two or more paths
  78. # to take based upon the remaining input. It tracks the starting token
  79. # of the offending input and also knows where the parser was
  80. # in the various paths when the error. Reported by reportNoViableAlternative()
  81. #
  82. class NoViableAltException(RecognitionException):
  83. def __init__(self, recognizer:Parser, input:TokenStream=None, startToken:Token=None,
  84. offendingToken:Token=None, deadEndConfigs:ATNConfigSet=None, ctx:ParserRuleContext=None):
  85. if ctx is None:
  86. ctx = recognizer._ctx
  87. if offendingToken is None:
  88. offendingToken = recognizer.getCurrentToken()
  89. if startToken is None:
  90. startToken = recognizer.getCurrentToken()
  91. if input is None:
  92. input = recognizer.getInputStream()
  93. super().__init__(recognizer=recognizer, input=input, ctx=ctx)
  94. # Which configurations did we try at input.index() that couldn't match input.LT(1)?#
  95. self.deadEndConfigs = deadEndConfigs
  96. # The token object at the start index; the input stream might
  97. # not be buffering tokens so get a reference to it. (At the
  98. # time the error occurred, of course the stream needs to keep a
  99. # buffer all of the tokens but later we might not have access to those.)
  100. self.startToken = startToken
  101. self.offendingToken = offendingToken
  102. # This signifies any kind of mismatched input exceptions such as
  103. # when the current input does not match the expected token.
  104. #
  105. class InputMismatchException(RecognitionException):
  106. def __init__(self, recognizer:Parser):
  107. super().__init__(recognizer=recognizer, input=recognizer.getInputStream(), ctx=recognizer._ctx)
  108. self.offendingToken = recognizer.getCurrentToken()
  109. # A semantic predicate failed during validation. Validation of predicates
  110. # occurs when normally parsing the alternative just like matching a token.
  111. # Disambiguating predicate evaluation occurs when we test a predicate during
  112. # prediction.
  113. class FailedPredicateException(RecognitionException):
  114. def __init__(self, recognizer:Parser, predicate:str=None, message:str=None):
  115. super().__init__(message=self.formatMessage(predicate,message), recognizer=recognizer,
  116. input=recognizer.getInputStream(), ctx=recognizer._ctx)
  117. s = recognizer._interp.atn.states[recognizer.state]
  118. trans = s.transitions[0]
  119. from antlr4.atn.Transition import PredicateTransition
  120. if isinstance(trans, PredicateTransition):
  121. self.ruleIndex = trans.ruleIndex
  122. self.predicateIndex = trans.predIndex
  123. else:
  124. self.ruleIndex = 0
  125. self.predicateIndex = 0
  126. self.predicate = predicate
  127. self.offendingToken = recognizer.getCurrentToken()
  128. def formatMessage(self, predicate:str, message:str):
  129. if message is not None:
  130. return message
  131. else:
  132. return "failed predicate: {" + predicate + "}?"
  133. class ParseCancellationException(CancellationException):
  134. pass
  135. del Token
  136. del Lexer
  137. del Parser
  138. del TokenStream
  139. del ATNConfigSet
  140. del ParserRulecontext
  141. del PredicateTransition
  142. del BufferedTokenStream