recoverInline method

  1. @override
Token recoverInline(
  1. Parser recognizer
)
override

{@inheritDoc}

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)

{@code LA(1)} is not what we are looking for. If {@code LA(2)} has the right token, however, then assume {@code LA(1)} is some extra spurious token and delete it. Then consume and return the next token (which was the {@code LA(2)} token) as the successful result of the match operation.

This recovery strategy is implemented by {@link #singleTokenDeletion}.

MISSING TOKEN (single token insertion)

If current token (at {@code LA(1)}) is consistent with what could come after the expected {@code LA(1)} token, then assume the token is missing and use the parser's [TokenFactory] 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 {@link #singleTokenInsertion}.

EXAMPLE

For example, Input {@code i=(3;} is clearly missing the {@code ')'}. 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 {@code ')'} at this point in the derivation:

=> ID '=' '(' INT ')' ('+' atom)* ';'
                   ^

The attempt to match {@code ')'} will fail when it sees {@code ';'} and call {@link #recoverInline}. To recover, it sees that {@code LA(1)==';'} is in the set of tokens that can follow the {@code ')'} token reference in rule atom. It can assume that you forgot the {@code ')'}.

Implementation

@override
Token recoverInline(Parser recognizer) {
// SINGLE TOKEN DELETION
  final matchedSymbol = singleTokenDeletion(recognizer);
  if (matchedSymbol != null) {
// we have deleted the extra token.
// now, move past ttype token as if all were ok
    recognizer.consume();
    return matchedSymbol;
  }

// SINGLE TOKEN INSERTION
  if (singleTokenInsertion(recognizer)) {
    return getMissingSymbol(recognizer);
  }

// even that didn't work; must throw the exception
  InputMismatchException e;
  if (nextTokensContext == null) {
    e = InputMismatchException(recognizer);
  } else {
    e = InputMismatchException(
      recognizer,
      nextTokensState!,
      nextTokensContext,
    );
  }

  throw e;
}