C# Class Antlr4.Runtime.DefaultErrorStrategy

This is the default implementation of IAntlrErrorStrategy used for error reporting and recovery in ANTLR parsers.
Inheritance: IAntlrErrorStrategy
Show file Open project: antlr/antlr4

Protected Properties

Property Type Description
errorRecoveryMode bool
lastErrorIndex int
lastErrorStates Antlr4.Runtime.Misc.IntervalSet

Public Methods

Method Description
InErrorRecoveryMode ( Parser recognizer ) : bool

Recover ( Parser recognizer, RecognitionException e ) : void

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.

RecoverInline ( Parser recognizer ) : IToken

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. If LA(2) has the right token, however, then assume LA(1) is some extra spurious token and delete it. Then consume and return the next token (which was the LA(2) token) as the successful result of the match operation.

This recovery strategy is implemented by SingleTokenDeletion(Parser) .

MISSING TOKEN (single token insertion)

If current token (at LA(1) ) is consistent with what could come after the expected LA(1) token, then assume the token is missing and use the parser's ITokenFactory 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(Parser) .

EXAMPLE

For example, Input i=(3; is clearly missing the ')' . When the parser returns from the nested call to expr , 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 call RecoverInline(Parser) . To recover, it sees that LA(1)==';' is in the set of tokens that can follow the ')' token reference in rule atom . It can assume that you forgot the ')' .

ReportError ( Parser recognizer, RecognitionException e ) : void

The default implementation returns immediately if the handler is already in error recovery mode. Otherwise, it calls BeginErrorCondition(Parser) and dispatches the reporting task based on the runtime type of e according to the following table.

  • NoViableAltException : Dispatches the call to ReportNoViableAlternative(Parser, NoViableAltException)
  • InputMismatchException : Dispatches the call to ReportInputMismatch(Parser, InputMismatchException)
  • FailedPredicateException : Dispatches the call to ReportFailedPredicate(Parser, FailedPredicateException)
  • All other types: calls Parser.NotifyErrorListeners(string) to report the exception

ReportMatch ( Parser recognizer ) : void

The default implementation simply calls EndErrorCondition(Parser) .

Reset ( Parser recognizer ) : void

The default implementation simply calls EndErrorCondition(Parser) to ensure that the handler is not in error recovery mode.

Sync ( Parser recognizer ) : void

The default implementation of IAntlrErrorStrategy.Sync(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(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 { }.

Protected Methods

Method Description
BeginErrorCondition ( Parser recognizer ) : void

This method is called to enter error recovery mode when a recognition exception is reported.

This method is called to enter error recovery mode when a recognition exception is reported.

ConstructToken ( ITokenSource tokenSource, int expectedTokenType, string tokenText, IToken current ) : IToken
ConsumeUntil ( Parser recognizer, IntervalSet set ) : void

Consume tokens until one matches the given token set.

Consume tokens until one matches the given token set.

EndErrorCondition ( Parser recognizer ) : void

This method is called to leave error recovery mode after recovering from a recognition exception.

This method is called to leave error recovery mode after recovering from a recognition exception.

GetSymbolText ( IToken symbol ) : string
GetSymbolType ( IToken symbol ) : int
GetTokenErrorDisplay ( IToken t ) : string

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.

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.

NotifyErrorListeners ( Parser recognizer, string message, RecognitionException e ) : void
ReportFailedPredicate ( Parser recognizer, FailedPredicateException e ) : void

This is called by ReportError(Parser, RecognitionException) when the exception is a FailedPredicateException .

ReportInputMismatch ( Parser recognizer, InputMismatchException e ) : void

This is called by ReportError(Parser, RecognitionException) when the exception is an InputMismatchException .

ReportMissingToken ( Parser recognizer ) : void

This method is called to report a syntax error which requires the insertion of a missing token into the input stream.

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(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(Parser) to enter error recovery mode, followed by calling Parser.NotifyErrorListeners(string) .

ReportNoViableAlternative ( Parser recognizer, NoViableAltException e ) : void

This is called by ReportError(Parser, RecognitionException) when the exception is a NoViableAltException .

ReportUnwantedToken ( Parser recognizer ) : void

This method is called to report a syntax error which requires the removal of a token from the input stream.

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 current LT(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(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(Parser) to enter error recovery mode, followed by calling Parser.NotifyErrorListeners(string) .

SingleTokenInsertion ( Parser recognizer ) : bool

This method implements the single-token insertion inline error recovery strategy.

This method implements the single-token insertion inline error recovery strategy. It is called by RecoverInline(Parser) if the single-token deletion strategy fails to recover from the mismatched input. If this method returns , 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 the LA(2) symbol. If this method returns , the caller is responsible for creating and inserting a token with the correct type to produce this behavior.

Private Methods

Method Description
EscapeWSAndQuote ( string s ) : string
GetErrorRecoverySet ( Parser recognizer ) : IntervalSet
GetExpectedTokens ( Parser recognizer ) : IntervalSet
GetMissingSymbol ( Parser recognizer ) : IToken
SingleTokenDeletion ( Parser recognizer ) : IToken

Method Details

BeginErrorCondition() protected method

This method is called to enter error recovery mode when a recognition exception is reported.
This method is called to enter error recovery mode when a recognition exception is reported.
protected BeginErrorCondition ( Parser recognizer ) : void
recognizer Parser the parser instance
return void

ConstructToken() protected method

protected ConstructToken ( ITokenSource tokenSource, int expectedTokenType, string tokenText, IToken current ) : IToken
tokenSource ITokenSource
expectedTokenType int
tokenText string
current IToken
return IToken

ConsumeUntil() protected method

Consume tokens until one matches the given token set.
Consume tokens until one matches the given token set.
protected ConsumeUntil ( Parser recognizer, IntervalSet set ) : void
recognizer Parser
set Antlr4.Runtime.Misc.IntervalSet
return void

EndErrorCondition() protected method

This method is called to leave error recovery mode after recovering from a recognition exception.
This method is called to leave error recovery mode after recovering from a recognition exception.
protected EndErrorCondition ( Parser recognizer ) : void
recognizer Parser
return void

GetSymbolText() protected method

protected GetSymbolText ( IToken symbol ) : string
symbol IToken
return string

GetSymbolType() protected method

protected GetSymbolType ( IToken symbol ) : int
symbol IToken
return int

GetTokenErrorDisplay() protected method

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.
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.
protected GetTokenErrorDisplay ( IToken t ) : string
t IToken
return string

InErrorRecoveryMode() public method

public InErrorRecoveryMode ( Parser recognizer ) : bool
recognizer Parser
return bool

NotifyErrorListeners() protected method

protected NotifyErrorListeners ( Parser recognizer, string message, RecognitionException e ) : void
recognizer Parser
message string
e RecognitionException
return void

Recover() public 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.

public Recover ( Parser recognizer, RecognitionException e ) : void
recognizer Parser
e RecognitionException
return void

RecoverInline() public method

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. If LA(2) has the right token, however, then assume LA(1) is some extra spurious token and delete it. Then consume and return the next token (which was the LA(2) token) as the successful result of the match operation.

This recovery strategy is implemented by SingleTokenDeletion(Parser) .

MISSING TOKEN (single token insertion)

If current token (at LA(1) ) is consistent with what could come after the expected LA(1) token, then assume the token is missing and use the parser's ITokenFactory 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(Parser) .

EXAMPLE

For example, Input i=(3; is clearly missing the ')' . When the parser returns from the nested call to expr , 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 call RecoverInline(Parser) . To recover, it sees that LA(1)==';' is in the set of tokens that can follow the ')' token reference in rule atom . It can assume that you forgot the ')' .
public RecoverInline ( Parser recognizer ) : IToken
recognizer Parser
return IToken

ReportError() public method

The default implementation returns immediately if the handler is already in error recovery mode. Otherwise, it calls BeginErrorCondition(Parser) and dispatches the reporting task based on the runtime type of e according to the following table.

  • NoViableAltException : Dispatches the call to ReportNoViableAlternative(Parser, NoViableAltException)
  • InputMismatchException : Dispatches the call to ReportInputMismatch(Parser, InputMismatchException)
  • FailedPredicateException : Dispatches the call to ReportFailedPredicate(Parser, FailedPredicateException)
  • All other types: calls Parser.NotifyErrorListeners(string) to report the exception
public ReportError ( Parser recognizer, RecognitionException e ) : void
recognizer Parser
e RecognitionException
return void

ReportFailedPredicate() protected method

This is called by ReportError(Parser, RecognitionException) when the exception is a FailedPredicateException .
protected ReportFailedPredicate ( Parser recognizer, FailedPredicateException e ) : void
recognizer Parser the parser instance
e FailedPredicateException the recognition exception
return void

ReportInputMismatch() protected method

This is called by ReportError(Parser, RecognitionException) when the exception is an InputMismatchException .
protected ReportInputMismatch ( Parser recognizer, InputMismatchException e ) : void
recognizer Parser the parser instance
e InputMismatchException the recognition exception
return void

ReportMatch() public method

The default implementation simply calls EndErrorCondition(Parser) .

public ReportMatch ( Parser recognizer ) : void
recognizer Parser
return void

ReportMissingToken() protected method

This method is called to report a syntax error which requires the insertion of a missing token into the input stream.
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(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(Parser) to enter error recovery mode, followed by calling Parser.NotifyErrorListeners(string) .

protected ReportMissingToken ( Parser recognizer ) : void
recognizer Parser the parser instance
return void

ReportNoViableAlternative() protected method

This is called by ReportError(Parser, RecognitionException) when the exception is a NoViableAltException .
protected ReportNoViableAlternative ( Parser recognizer, NoViableAltException e ) : void
recognizer Parser the parser instance
e NoViableAltException the recognition exception
return void

ReportUnwantedToken() protected method

This method is called to report a syntax error which requires the removal of a token from the input stream.
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 current LT(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(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(Parser) to enter error recovery mode, followed by calling Parser.NotifyErrorListeners(string) .

protected ReportUnwantedToken ( Parser recognizer ) : void
recognizer Parser the parser instance
return void

Reset() public method

The default implementation simply calls EndErrorCondition(Parser) to ensure that the handler is not in error recovery mode.

public Reset ( Parser recognizer ) : void
recognizer Parser
return void

SingleTokenInsertion() protected method

This method implements the single-token insertion inline error recovery strategy.
This method implements the single-token insertion inline error recovery strategy. It is called by RecoverInline(Parser) if the single-token deletion strategy fails to recover from the mismatched input. If this method returns , 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 the LA(2) symbol. If this method returns , the caller is responsible for creating and inserting a token with the correct type to produce this behavior.

protected SingleTokenInsertion ( Parser recognizer ) : bool
recognizer Parser the parser instance
return bool

Sync() public method

The default implementation of IAntlrErrorStrategy.Sync(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(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 { }.

public Sync ( Parser recognizer ) : void
recognizer Parser
return void

Property Details

errorRecoveryMode protected property

Indicates whether the error strategy is currently "recovering from an error".
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.
protected bool errorRecoveryMode
return bool

lastErrorIndex protected property

The index into the input stream where the last error occurred.
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.
protected int lastErrorIndex
return int

lastErrorStates protected property

protected IntervalSet,Antlr4.Runtime.Misc lastErrorStates
return Antlr4.Runtime.Misc.IntervalSet