00001 """ANTLR3 exception hierarchy"""
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 from constants import INVALID_TOKEN_TYPE
00034
00035
00036 class BacktrackingFailed(Exception):
00037 """@brief Raised to signal failed backtrack attempt"""
00038
00039 pass
00040
00041
00042 class RecognitionException(Exception):
00043 """@brief The root of the ANTLR exception hierarchy.
00044
00045 To avoid English-only error messages and to generally make things
00046 as flexible as possible, these exceptions are not created with strings,
00047 but rather the information necessary to generate an error. Then
00048 the various reporting methods in Parser and Lexer can be overridden
00049 to generate a localized error message. For example, MismatchedToken
00050 exceptions are built with the expected token type.
00051 So, don't expect getMessage() to return anything.
00052
00053 Note that as of Java 1.4, you can access the stack trace, which means
00054 that you can compute the complete trace of rules from the start symbol.
00055 This gives you considerable context information with which to generate
00056 useful error messages.
00057
00058 ANTLR generates code that throws exceptions upon recognition error and
00059 also generates code to catch these exceptions in each rule. If you
00060 want to quit upon first error, you can turn off the automatic error
00061 handling mechanism using rulecatch action, but you still need to
00062 override methods mismatch and recoverFromMismatchSet.
00063
00064 In general, the recognition exceptions can track where in a grammar a
00065 problem occurred and/or what was the expected input. While the parser
00066 knows its state (such as current input symbol and line info) that
00067 state can change before the exception is reported so current token index
00068 is computed and stored at exception time. From this info, you can
00069 perhaps print an entire line of input not just a single token, for example.
00070 Better to just say the recognizer had a problem and then let the parser
00071 figure out a fancy report.
00072
00073 """
00074
00075 def __init__(self, input=None):
00076 Exception.__init__(self)
00077
00078
00079 self.input = None
00080
00081
00082
00083 self.index = None
00084
00085
00086
00087
00088 self.token = None
00089
00090
00091
00092 self.node = None
00093
00094
00095 self.c = None
00096
00097
00098
00099
00100 self.line = None
00101
00102 self.charPositionInLine = None
00103
00104
00105
00106
00107
00108 self.approximateLineInfo = False
00109
00110
00111 if input is not None:
00112 self.input = input
00113 self.index = input.index()
00114
00115
00116 from streams import TokenStream, CharStream
00117 from tree import TreeNodeStream
00118
00119 if isinstance(self.input, TokenStream):
00120 self.token = self.input.LT(1)
00121 self.line = self.token.line
00122 self.charPositionInLine = self.token.charPositionInLine
00123
00124 if isinstance(self.input, TreeNodeStream):
00125 self.extractInformationFromTreeNodeStream(self.input)
00126
00127 else:
00128 if isinstance(self.input, CharStream):
00129 self.c = self.input.LT(1)
00130 self.line = self.input.line
00131 self.charPositionInLine = self.input.charPositionInLine
00132
00133 else:
00134 self.c = self.input.LA(1)
00135
00136 def extractInformationFromTreeNodeStream(self, nodes):
00137 from tree import Tree, CommonTree
00138 from tokens import CommonToken
00139
00140 self.node = nodes.LT(1)
00141 adaptor = nodes.adaptor
00142 payload = adaptor.getToken(self.node)
00143 if payload is not None:
00144 self.token = payload
00145 if payload.line <= 0:
00146
00147 i = -1
00148 priorNode = nodes.LT(i)
00149 while priorNode is not None:
00150 priorPayload = adaptor.getToken(priorNode)
00151 if priorPayload is not None and priorPayload.line > 0:
00152
00153 self.line = priorPayload.line
00154 self.charPositionInLine = priorPayload.charPositionInLine
00155 self.approximateLineInfo = True
00156 break
00157
00158 i -= 1
00159 priorNode = nodes.LT(i)
00160
00161 else:
00162 self.line = payload.line
00163 self.charPositionInLine = payload.charPositionInLine
00164
00165 elif isinstance(self.node, Tree):
00166 self.line = self.node.line
00167 self.charPositionInLine = self.node.charPositionInLine
00168 if isinstance(self.node, CommonTree):
00169 self.token = self.node.token
00170
00171 else:
00172 type = adaptor.getType(self.node)
00173 text = adaptor.getText(self.node)
00174 self.token = CommonToken(type=type, text=text)
00175
00176
00177 def getUnexpectedType(self):
00178 """Return the token type or char of the unexpected input element"""
00179
00180 from streams import TokenStream
00181 from tree import TreeNodeStream
00182
00183 if isinstance(self.input, TokenStream):
00184 return self.token.type
00185
00186 elif isinstance(self.input, TreeNodeStream):
00187 adaptor = self.input.treeAdaptor
00188 return adaptor.getType(self.node)
00189
00190 else:
00191 return self.c
00192
00193 unexpectedType = property(getUnexpectedType)
00194
00195
00196 class MismatchedTokenException(RecognitionException):
00197 """@brief A mismatched char or Token or tree node."""
00198
00199 def __init__(self, expecting, input):
00200 RecognitionException.__init__(self, input)
00201 self.expecting = expecting
00202
00203
00204 def __str__(self):
00205
00206 return "MismatchedTokenException(%r!=%r)" % (
00207 self.getUnexpectedType(), self.expecting
00208 )
00209 __repr__ = __str__
00210
00211
00212 class UnwantedTokenException(MismatchedTokenException):
00213 """An extra token while parsing a TokenStream"""
00214
00215 def getUnexpectedToken(self):
00216 return self.token
00217
00218
00219 def __str__(self):
00220 exp = ", expected %s" % self.expecting
00221 if self.expecting == INVALID_TOKEN_TYPE:
00222 exp = ""
00223
00224 if self.token is None:
00225 return "UnwantedTokenException(found=%s%s)" % (None, exp)
00226
00227 return "UnwantedTokenException(found=%s%s)" % (self.token.text, exp)
00228 __repr__ = __str__
00229
00230
00231 class MissingTokenException(MismatchedTokenException):
00232 """
00233 We were expecting a token but it's not found. The current token
00234 is actually what we wanted next.
00235 """
00236
00237 def __init__(self, expecting, input, inserted):
00238 MismatchedTokenException.__init__(self, expecting, input)
00239
00240 self.inserted = inserted
00241
00242
00243 def getMissingType(self):
00244 return self.expecting
00245
00246
00247 def __str__(self):
00248 if self.inserted is not None and self.token is not None:
00249 return "MissingTokenException(inserted %r at %r)" % (
00250 self.inserted, self.token.text)
00251
00252 if self.token is not None:
00253 return "MissingTokenException(at %r)" % self.token.text
00254
00255 return "MissingTokenException"
00256 __repr__ = __str__
00257
00258
00259 class MismatchedRangeException(RecognitionException):
00260 """@brief The next token does not match a range of expected types."""
00261
00262 def __init__(self, a, b, input):
00263 RecognitionException.__init__(self, input)
00264
00265 self.a = a
00266 self.b = b
00267
00268
00269 def __str__(self):
00270 return "MismatchedRangeException(%r not in [%r..%r])" % (
00271 self.getUnexpectedType(), self.a, self.b
00272 )
00273 __repr__ = __str__
00274
00275
00276 class MismatchedSetException(RecognitionException):
00277 """@brief The next token does not match a set of expected types."""
00278
00279 def __init__(self, expecting, input):
00280 RecognitionException.__init__(self, input)
00281
00282 self.expecting = expecting
00283
00284
00285 def __str__(self):
00286 return "MismatchedSetException(%r not in %r)" % (
00287 self.getUnexpectedType(), self.expecting
00288 )
00289 __repr__ = __str__
00290
00291
00292 class MismatchedNotSetException(MismatchedSetException):
00293 """@brief Used for remote debugger deserialization"""
00294
00295 def __str__(self):
00296 return "MismatchedNotSetException(%r!=%r)" % (
00297 self.getUnexpectedType(), self.expecting
00298 )
00299 __repr__ = __str__
00300
00301
00302 class NoViableAltException(RecognitionException):
00303 """@brief Unable to decide which alternative to choose."""
00304
00305 def __init__(
00306 self, grammarDecisionDescription, decisionNumber, stateNumber, input
00307 ):
00308 RecognitionException.__init__(self, input)
00309
00310 self.grammarDecisionDescription = grammarDecisionDescription
00311 self.decisionNumber = decisionNumber
00312 self.stateNumber = stateNumber
00313
00314
00315 def __str__(self):
00316 return "NoViableAltException(%r!=[%r])" % (
00317 self.unexpectedType, self.grammarDecisionDescription
00318 )
00319 __repr__ = __str__
00320
00321
00322 class EarlyExitException(RecognitionException):
00323 """@brief The recognizer did not match anything for a (..)+ loop."""
00324
00325 def __init__(self, decisionNumber, input):
00326 RecognitionException.__init__(self, input)
00327
00328 self.decisionNumber = decisionNumber
00329
00330
00331 class FailedPredicateException(RecognitionException):
00332 """@brief A semantic predicate failed during validation.
00333
00334 Validation of predicates
00335 occurs when normally parsing the alternative just like matching a token.
00336 Disambiguating predicate evaluation occurs when we hoist a predicate into
00337 a prediction decision.
00338 """
00339
00340 def __init__(self, input, ruleName, predicateText):
00341 RecognitionException.__init__(self, input)
00342
00343 self.ruleName = ruleName
00344 self.predicateText = predicateText
00345
00346
00347 def __str__(self):
00348 return "FailedPredicateException("+self.ruleName+",{"+self.predicateText+"}?)"
00349 __repr__ = __str__
00350
00351
00352 class MismatchedTreeNodeException(RecognitionException):
00353 """@brief The next tree mode does not match the expected type."""
00354
00355 def __init__(self, expecting, input):
00356 RecognitionException.__init__(self, input)
00357
00358 self.expecting = expecting
00359
00360 def __str__(self):
00361 return "MismatchedTreeNodeException(%r!=%r)" % (
00362 self.getUnexpectedType(), self.expecting
00363 )
00364 __repr__ = __str__