/// <summary> /// Rely on the error handler for this parser but, if no tokens are consumed /// to recover, add an error node. /// </summary> /// <remarks> /// Rely on the error handler for this parser but, if no tokens are consumed /// to recover, add an error node. Otherwise, nothing is seen in the parse /// tree. /// </remarks> protected internal virtual void Recover(RecognitionException e) { int i = _input.Index; ErrorHandler.Recover(this, e); if (_input.Index == i) { // no input consumed, better add an error node if (e is InputMismatchException) { InputMismatchException ime = (InputMismatchException)e; IToken tok = e.OffendingToken; int expectedTokenType = ime.GetExpectedTokens().MinElement; // get any element IToken errToken = TokenFactory.Create(Tuple.Create(tok.TokenSource, tok.TokenSource.InputStream), expectedTokenType, tok.Text, TokenConstants.DefaultChannel, -1, -1, tok.Line, tok.Column); // invalid start/stop _ctx.AddErrorNode(errToken); } else { // NoViableAlt IToken tok = e.OffendingToken; IToken errToken = TokenFactory.Create(Tuple.Create(tok.TokenSource, tok.TokenSource.InputStream), TokenConstants.InvalidType, tok.Text, TokenConstants.DefaultChannel, -1, -1, tok.Line, tok.Column); // invalid start/stop _ctx.AddErrorNode(errToken); } } }
/// <summary> /// <inheritDoc/> /// <p>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 /// <see cref="InputMismatchException"/> /// .</p> /// <p><strong>EXTRA TOKEN</strong> (single token deletion)</p> /// <p> /// <c>LA(1)</c> /// is not what we are looking for. If /// <c>LA(2)</c> /// has the /// right token, however, then assume /// <c>LA(1)</c> /// is some extra spurious /// token and delete it. Then consume and return the next token (which was /// the /// <c>LA(2)</c> /// token) as the successful result of the match operation.</p> /// <p>This recovery strategy is implemented by /// <see cref="SingleTokenDeletion(Parser)"/> /// .</p> /// <p><strong>MISSING TOKEN</strong> (single token insertion)</p> /// <p>If current token (at /// <c>LA(1)</c> /// ) is consistent with what could come /// after the expected /// <c>LA(1)</c> /// token, then assume the token is missing /// and use the parser's /// <see cref="ITokenFactory"/> /// to create it on the fly. The /// "insertion" is performed by returning the created token as the successful /// result of the match operation.</p> /// <p>This recovery strategy is implemented by /// <see cref="SingleTokenInsertion(Parser)"/> /// .</p> /// <p><strong>EXAMPLE</strong></p> /// <p>For example, Input /// <c>i=(3;</c> /// is clearly missing the /// <c>')'</c> /// . When /// the parser returns from the nested call to /// <c>expr</c> /// , it will have /// call chain:</p> /// <pre> /// stat → expr → atom /// </pre> /// and it will be trying to match the /// <c>')'</c> /// at this point in the /// derivation: /// <pre> /// => ID '=' '(' INT ')' ('+' atom)* ';' /// ^ /// </pre> /// The attempt to match /// <c>')'</c> /// will fail when it sees /// <c>';'</c> /// and /// call /// <see cref="RecoverInline(Parser)"/> /// . To recover, it sees that /// <c>LA(1)==';'</c> /// is in the set of tokens that can follow the /// <c>')'</c> /// token reference /// in rule /// <c>atom</c> /// . It can assume that you forgot the /// <c>')'</c> /// . /// </summary> /// <exception cref="Antlr4.Runtime.RecognitionException"/> public virtual IToken RecoverInline(Parser recognizer) { // SINGLE TOKEN DELETION IToken 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 //throw new InputMismatchException(recognizer); InputMismatchException e; if (nextTokensContext == null) { e = new InputMismatchException(recognizer); } else { e = new InputMismatchException(recognizer, nextTokensState, nextTokensContext); } throw e; }
/// <summary> /// This is called by /// <see cref="ReportError(Parser, RecognitionException)">ReportError(Parser, RecognitionException) /// </see> /// when the exception is an /// <see cref="InputMismatchException">InputMismatchException</see> /// . /// </summary> /// <seealso cref="ReportError(Parser, RecognitionException)">ReportError(Parser, RecognitionException) /// </seealso> /// <param name="recognizer">the parser instance</param> /// <param name="e">the recognition exception</param> protected internal virtual void ReportInputMismatch(Parser recognizer, InputMismatchException e) { string msg = "mismatched input " + GetTokenErrorDisplay(e.OffendingToken) + " expecting " + e.GetExpectedTokens().ToString(recognizer.TokenNames); NotifyErrorListeners(recognizer, msg, e); }
/// <summary> /// Make sure we don't attempt to recover inline; if the parser /// successfully recovers, it won't throw an exception. /// </summary> /// <exception cref="Antlr4.Runtime.RecognitionException"/> public override IToken RecoverInline(Parser recognizer) { InputMismatchException e = new InputMismatchException(recognizer); for (ParserRuleContext context = recognizer.Context; context != null; context = ((ParserRuleContext)context.Parent)) { context.exception = e; } throw new ParseCanceledException(e); }
/// <summary> /// Make sure we don't attempt to recover inline; if the parser /// successfully recovers, it won't throw an exception. /// </summary> /// <remarks> /// Make sure we don't attempt to recover inline; if the parser /// successfully recovers, it won't throw an exception. /// </remarks> /// <exception cref="Antlr4.Runtime.RecognitionException"/> public override IToken RecoverInline(Parser recognizer) { InputMismatchException e = new InputMismatchException(recognizer); for (ParserRuleContext context = recognizer.Context; context != null; context = ((ParserRuleContext)context.Parent)) { context.exception = e; } throw new ParseCanceledException(e); }
/// <summary> /// This is called by /// <see cref="ReportError(Parser, RecognitionException)"/> /// when the exception is an /// <see cref="InputMismatchException"/> /// . /// </summary> /// <seealso cref="ReportError(Parser, RecognitionException)"/> /// <param name="recognizer">the parser instance</param> /// <param name="e">the recognition exception</param> protected internal virtual void ReportInputMismatch(Parser recognizer, InputMismatchException e) { string msg = "mismatched input " + GetTokenErrorDisplay(e.OffendingToken) + " expecting " + e.GetExpectedTokens().ToString(recognizer.Vocabulary); NotifyErrorListeners(recognizer, msg, e); }
public override IToken RecoverInline(Parser recognizer) { int errIndex = recognizer.InputStream.Index; if (firstErrorTokenIndex == -1) { firstErrorTokenIndex = errIndex; // latch } // System.err.println("recoverInline: error at " + errIndex); InputMismatchException e = new InputMismatchException(recognizer); // TokenStream input = recognizer.getInputStream(); // seek EOF // input.seek(input.size() - 1); throw e; }