Class DefaultErrorStrategy
- java.lang.Object
-
- org.antlr.v4.runtime.DefaultErrorStrategy
-
- All Implemented Interfaces:
ANTLRErrorStrategy
- Direct Known Subclasses:
BailErrorStrategy
public class DefaultErrorStrategy extends Object implements ANTLRErrorStrategy
This is the default implementation ofANTLRErrorStrategy
used for error reporting and recovery in ANTLR parsers.
-
-
Field Summary
Fields Modifier and Type Field Description protected boolean
errorRecoveryMode
Indicates whether the error strategy is currently "recovering from an error".protected int
lastErrorIndex
The index into the input stream where the last error occurred.protected IntervalSet
lastErrorStates
protected ParserRuleContext
nextTokensContext
This field is used to propagate information about the lookahead following the previous match.protected int
nextTokensState
-
Constructor Summary
Constructors Constructor Description DefaultErrorStrategy()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected void
beginErrorCondition(Parser recognizer)
This method is called to enter error recovery mode when a recognition exception is reported.protected void
consumeUntil(Parser recognizer, IntervalSet set)
Consume tokens until one matches the given token set.protected void
endErrorCondition(Parser recognizer)
This method is called to leave error recovery mode after recovering from a recognition exception.protected String
escapeWSAndQuote(String s)
protected IntervalSet
getErrorRecoverySet(Parser recognizer)
protected IntervalSet
getExpectedTokens(Parser recognizer)
protected Token
getMissingSymbol(Parser recognizer)
Conjure up a missing token during error recovery.protected String
getSymbolText(Token symbol)
protected int
getSymbolType(Token symbol)
protected String
getTokenErrorDisplay(Token t)
How should a token be displayed in an error message? The default is to display just the text, but during development you might want to have a lot of information spit out.boolean
inErrorRecoveryMode(Parser recognizer)
Tests whether or notrecognizer
is in the process of recovering from an error.void
recover(Parser recognizer, RecognitionException e)
This method is called to recover from exceptione
.Token
recoverInline(Parser recognizer)
This method is called when an unexpected symbol is encountered during an inline match operation, such asParser.match(int)
.void
reportError(Parser recognizer, RecognitionException e)
Report any kind ofRecognitionException
.protected void
reportFailedPredicate(Parser recognizer, FailedPredicateException e)
This is called byreportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
when the exception is aFailedPredicateException
.protected void
reportInputMismatch(Parser recognizer, InputMismatchException e)
This is called byreportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
when the exception is anInputMismatchException
.void
reportMatch(Parser recognizer)
This method is called by when the parser successfully matches an input symbol.protected void
reportMissingToken(Parser recognizer)
This method is called to report a syntax error which requires the insertion of a missing token into the input stream.protected void
reportNoViableAlternative(Parser recognizer, NoViableAltException e)
This is called byreportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
when the exception is aNoViableAltException
.protected void
reportUnwantedToken(Parser recognizer)
This method is called to report a syntax error which requires the removal of a token from the input stream.void
reset(Parser recognizer)
Reset the error handler state for the specifiedrecognizer
.protected Token
singleTokenDeletion(Parser recognizer)
This method implements the single-token deletion inline error recovery strategy.protected boolean
singleTokenInsertion(Parser recognizer)
This method implements the single-token insertion inline error recovery strategy.void
sync(Parser recognizer)
The default implementation ofANTLRErrorStrategy.sync(org.antlr.v4.runtime.Parser)
makes sure that the current lookahead symbol is consistent with what were expecting at this point in the ATN.
-
-
-
Field Detail
-
errorRecoveryMode
protected boolean errorRecoveryMode
Indicates whether the error strategy is currently "recovering from an error". This is used to suppress reporting multiple error messages while attempting to recover from a detected syntax error.
-
lastErrorIndex
protected int lastErrorIndex
The index into the input stream where the last error occurred. This is used to prevent infinite loops where an error is found but no token is consumed during recovery...another error is found, ad nauseum. This is a failsafe mechanism to guarantee that at least one token/tree node is consumed for two errors.
-
lastErrorStates
protected IntervalSet lastErrorStates
-
nextTokensContext
protected ParserRuleContext nextTokensContext
This field is used to propagate information about the lookahead following the previous match. Since prediction prefers completing the current rule to error recovery efforts, error reporting may occur later than the original point where it was discoverable. The original context is used to compute the true expected sets as though the reporting occurred as early as possible.
-
nextTokensState
protected int nextTokensState
- See Also:
nextTokensContext
-
-
Method Detail
-
reset
public void reset(Parser recognizer)
Reset the error handler state for the specifiedrecognizer
.The default implementation simply calls
endErrorCondition(org.antlr.v4.runtime.Parser)
to ensure that the handler is not in error recovery mode.- Specified by:
reset
in interfaceANTLRErrorStrategy
- Parameters:
recognizer
- the parser instance
-
beginErrorCondition
protected void beginErrorCondition(Parser recognizer)
This method is called to enter error recovery mode when a recognition exception is reported.- Parameters:
recognizer
- the parser instance
-
inErrorRecoveryMode
public boolean inErrorRecoveryMode(Parser recognizer)
Tests whether or notrecognizer
is in the process of recovering from an error. In error recovery mode,Parser.consume()
adds symbols to the parse tree by callingParser.createErrorNode(ParserRuleContext, Token)
thenParserRuleContext.addErrorNode(ErrorNode)
instead ofParser.createTerminalNode(ParserRuleContext, Token)
.- Specified by:
inErrorRecoveryMode
in interfaceANTLRErrorStrategy
- Parameters:
recognizer
- the parser instance- Returns:
true
if the parser is currently recovering from a parse error, otherwisefalse
-
endErrorCondition
protected void endErrorCondition(Parser recognizer)
This method is called to leave error recovery mode after recovering from a recognition exception.- Parameters:
recognizer
-
-
reportMatch
public void reportMatch(Parser recognizer)
This method is called by when the parser successfully matches an input symbol.The default implementation simply calls
endErrorCondition(org.antlr.v4.runtime.Parser)
.- Specified by:
reportMatch
in interfaceANTLRErrorStrategy
- Parameters:
recognizer
- the parser instance
-
reportError
public void reportError(Parser recognizer, RecognitionException e)
Report any kind ofRecognitionException
. This method is called by the default exception handler generated for a rule method.The default implementation returns immediately if the handler is already in error recovery mode. Otherwise, it calls
beginErrorCondition(org.antlr.v4.runtime.Parser)
and dispatches the reporting task based on the runtime type ofe
according to the following table.NoViableAltException
: Dispatches the call toreportNoViableAlternative(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.NoViableAltException)
InputMismatchException
: Dispatches the call toreportInputMismatch(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.InputMismatchException)
FailedPredicateException
: Dispatches the call toreportFailedPredicate(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.FailedPredicateException)
- All other types: calls
Parser.notifyErrorListeners(java.lang.String)
to report the exception
- Specified by:
reportError
in interfaceANTLRErrorStrategy
- Parameters:
recognizer
- the parser instancee
- the recognition exception to report
-
recover
public void recover(Parser recognizer, RecognitionException e)
This method is called to recover from exceptione
. This method is called afterANTLRErrorStrategy.reportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
by the default exception handler generated for a rule method.The default implementation resynchronizes the parser by consuming tokens until we find one in the resynchronization set--loosely the set of tokens that can follow the current rule.
- Specified by:
recover
in interfaceANTLRErrorStrategy
- Parameters:
recognizer
- the parser instancee
- the recognition exception to recover from- See Also:
ANTLRErrorStrategy.reportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
-
sync
public void sync(Parser recognizer) throws RecognitionException
The default implementation ofANTLRErrorStrategy.sync(org.antlr.v4.runtime.Parser)
makes sure that the current lookahead symbol is consistent with what were expecting at this point in the ATN. You can call this anytime but ANTLR only generates code to check before subrules/loops and each iteration.Implements Jim Idle's magic sync mechanism in closures and optional subrules. E.g.,
a : sync ( stuff sync )* ; sync : {consume to what can follow sync} ;
At the start of a sub rule upon error,sync(org.antlr.v4.runtime.Parser)
performs single token deletion, if possible. If it can't do that, it bails on the current rule and uses the default error recovery, which consumes until the resynchronization set of the current rule.If the sub rule is optional (
(...)?
,(...)*
, or block with an empty alternative), then the expected set includes what follows the subrule.During loop iteration, it consumes until it sees a token that can start a sub rule or what follows loop. Yes, that is pretty aggressive. We opt to stay in the loop as long as possible.
ORIGINS
Previous versions of ANTLR did a poor job of their recovery within loops. A single mismatch token or missing token would force the parser to bail out of the entire rules surrounding the loop. So, for rule
classDef : 'class' ID '{' member* '}'
input with an extra token between members would force the parser to consume until it found the next class definition rather than the next member definition of the current class.This functionality cost a little bit of effort because the parser has to compare token set at the start of the loop and at each iteration. If for some reason speed is suffering for you, you can turn off this functionality by simply overriding this method as a blank { }.
- Specified by:
sync
in interfaceANTLRErrorStrategy
- Parameters:
recognizer
- the parser instance- Throws:
RecognitionException
- if an error is detected by the error strategy but cannot be automatically recovered at the current state in the parsing process- See Also:
sync(org.antlr.v4.runtime.Parser)
-
reportNoViableAlternative
protected void reportNoViableAlternative(Parser recognizer, NoViableAltException e)
This is called byreportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
when the exception is aNoViableAltException
.- Parameters:
recognizer
- the parser instancee
- the recognition exception- See Also:
reportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
-
reportInputMismatch
protected void reportInputMismatch(Parser recognizer, InputMismatchException e)
This is called byreportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
when the exception is anInputMismatchException
.- Parameters:
recognizer
- the parser instancee
- the recognition exception- See Also:
reportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
-
reportFailedPredicate
protected void reportFailedPredicate(Parser recognizer, FailedPredicateException e)
This is called byreportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
when the exception is aFailedPredicateException
.- Parameters:
recognizer
- the parser instancee
- the recognition exception- See Also:
reportError(org.antlr.v4.runtime.Parser, org.antlr.v4.runtime.RecognitionException)
-
reportUnwantedToken
protected void reportUnwantedToken(Parser recognizer)
This method is called to report a syntax error which requires the removal of a token from the input stream. At the time this method is called, the erroneous symbol is currentLT(1)
symbol and has not yet been removed from the input stream. When this method returns,recognizer
is in error recovery mode.This method is called when
singleTokenDeletion(org.antlr.v4.runtime.Parser)
identifies single-token deletion as a viable recovery strategy for a mismatched input error.The default implementation simply returns if the handler is already in error recovery mode. Otherwise, it calls
beginErrorCondition(org.antlr.v4.runtime.Parser)
to enter error recovery mode, followed by callingParser.notifyErrorListeners(java.lang.String)
.- Parameters:
recognizer
- the parser instance
-
reportMissingToken
protected void reportMissingToken(Parser recognizer)
This method is called to report a syntax error which requires the insertion of a missing token into the input stream. At the time this method is called, the missing token has not yet been inserted. When this method returns,recognizer
is in error recovery mode.This method is called when
singleTokenInsertion(org.antlr.v4.runtime.Parser)
identifies single-token insertion as a viable recovery strategy for a mismatched input error.The default implementation simply returns if the handler is already in error recovery mode. Otherwise, it calls
beginErrorCondition(org.antlr.v4.runtime.Parser)
to enter error recovery mode, followed by callingParser.notifyErrorListeners(java.lang.String)
.- Parameters:
recognizer
- the parser instance
-
recoverInline
public Token recoverInline(Parser recognizer) throws RecognitionException
This method is called when an unexpected symbol is encountered during an inline match operation, such asParser.match(int)
. If the error strategy successfully recovers from the match failure, this method returns theToken
instance which should be treated as the successful result of the match.This method handles the consumption of any tokens - the caller should not call
Parser.consume()
after a successful recovery.Note that the calling code will not report an error if this method returns successfully. The error strategy implementation is responsible for calling
Parser.notifyErrorListeners(java.lang.String)
as appropriate.The default implementation attempts to recover from the mismatched input by using single token insertion and deletion as described below. If the recovery attempt fails, this method throws an
InputMismatchException
.EXTRA TOKEN (single token deletion)
LA(1)
is not what we are looking for. IfLA(2)
has the right token, however, then assumeLA(1)
is some extra spurious token and delete it. Then consume and return the next token (which was theLA(2)
token) as the successful result of the match operation.This recovery strategy is implemented by
singleTokenDeletion(org.antlr.v4.runtime.Parser)
.MISSING TOKEN (single token insertion)
If current token (at
LA(1)
) is consistent with what could come after the expectedLA(1)
token, then assume the token is missing and use the parser'sTokenFactory
to create it on the fly. The "insertion" is performed by returning the created token as the successful result of the match operation.This recovery strategy is implemented by
singleTokenInsertion(org.antlr.v4.runtime.Parser)
.EXAMPLE
For example, Input
i=(3;
is clearly missing the')'
. When the parser returns from the nested call toexpr
, it will have call chain:stat → expr → atom
and it will be trying to match the')'
at this point in the derivation:=> ID '=' '(' INT ')' ('+' atom)* ';' ^
The attempt to match')'
will fail when it sees';'
and callrecoverInline(org.antlr.v4.runtime.Parser)
. To recover, it sees thatLA(1)==';'
is in the set of tokens that can follow the')'
token reference in ruleatom
. It can assume that you forgot the')'
.- Specified by:
recoverInline
in interfaceANTLRErrorStrategy
- Parameters:
recognizer
- the parser instance- Throws:
RecognitionException
- if the error strategy was not able to recover from the unexpected input symbol
-
singleTokenInsertion
protected boolean singleTokenInsertion(Parser recognizer)
This method implements the single-token insertion inline error recovery strategy. It is called byrecoverInline(org.antlr.v4.runtime.Parser)
if the single-token deletion strategy fails to recover from the mismatched input. If this method returnstrue
,recognizer
will be in error recovery mode.This method determines whether or not single-token insertion is viable by checking if the
LA(1)
input symbol could be successfully matched if it were instead theLA(2)
symbol. If this method returnstrue
, the caller is responsible for creating and inserting a token with the correct type to produce this behavior.- Parameters:
recognizer
- the parser instance- Returns:
true
if single-token insertion is a viable recovery strategy for the current mismatched input, otherwisefalse
-
singleTokenDeletion
protected Token singleTokenDeletion(Parser recognizer)
This method implements the single-token deletion inline error recovery strategy. It is called byrecoverInline(org.antlr.v4.runtime.Parser)
to attempt to recover from mismatched input. If this method returns null, the parser and error handler state will not have changed. If this method returns non-null,recognizer
will not be in error recovery mode since the returned token was a successful match.If the single-token deletion is successful, this method calls
reportUnwantedToken(org.antlr.v4.runtime.Parser)
to report the error, followed byParser.consume()
to actually "delete" the extraneous token. Then, before returningreportMatch(org.antlr.v4.runtime.Parser)
is called to signal a successful match.- Parameters:
recognizer
- the parser instance- Returns:
- the successfully matched
Token
instance if single-token deletion successfully recovers from the mismatched input, otherwisenull
-
getMissingSymbol
protected Token getMissingSymbol(Parser recognizer)
Conjure up a missing token during error recovery. The recognizer attempts to recover from single missing symbols. But, actions might refer to that missing symbol. For example, x=ID {f($x);}. The action clearly assumes that there has been an identifier matched previously and that $x points at that token. If that token is missing, but the next token in the stream is what we want we assume that this token is missing and we keep going. Because we have to return some token to replace the missing token, we have to conjure one up. This method gives the user control over the tokens returned for missing tokens. Mostly, you will want to create something special for identifier tokens. For literals such as '{' and ',', the default action in the parser or tree parser works. It simply creates a CommonToken of the appropriate type. The text will be the token. If you change what tokens must be created by the lexer, override this method to create the appropriate tokens.
-
getExpectedTokens
protected IntervalSet getExpectedTokens(Parser recognizer)
-
getTokenErrorDisplay
protected String getTokenErrorDisplay(Token t)
How should a token be displayed in an error message? The default is to display just the text, but during development you might want to have a lot of information spit out. Override in that case to use t.toString() (which, for CommonToken, dumps everything about the token). This is better than forcing you to override a method in your token objects because you don't have to go modify your lexer so that it creates a new Java type.
-
getSymbolType
protected int getSymbolType(Token symbol)
-
getErrorRecoverySet
protected IntervalSet getErrorRecoverySet(Parser recognizer)
-
consumeUntil
protected void consumeUntil(Parser recognizer, IntervalSet set)
Consume tokens until one matches the given token set.
-
-