/// <summary> /// Checks whether or not /// <paramref name="symbol"/> /// can follow the current state in the /// ATN. The behavior of this method is equivalent to the following, but is /// implemented such that the complete context-sensitive follow set does not /// need to be explicitly constructed. /// <pre> /// return getExpectedTokens().contains(symbol); /// </pre> /// </summary> /// <param name="symbol">the symbol type to check</param> /// <returns> /// /// <see langword="true"/> /// if /// <paramref name="symbol"/> /// can follow the current state in /// the ATN, otherwise /// <see langword="false"/> /// . /// </returns> public virtual bool IsExpectedToken(int symbol) { // return getInterpreter().atn.nextTokens(_ctx); ATN atn = Interpreter.atn; ParserRuleContext ctx = _ctx; ATNState s = atn.states[State]; IntervalSet following = atn.NextTokens(s); if (following.Contains(symbol)) { return(true); } // System.out.println("following "+s+"="+following); if (!following.Contains(TokenConstants.Epsilon)) { return(false); } while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.Epsilon)) { ATNState invokingState = atn.states[ctx.invokingState]; RuleTransition rt = (RuleTransition)invokingState.Transition(0); following = atn.NextTokens(rt.followState); if (following.Contains(symbol)) { return(true); } ctx = (ParserRuleContext)ctx.parent; } if (following.Contains(TokenConstants.Epsilon) && symbol == TokenConstants.Eof) { return(true); } return(false); }
public virtual IntervalSet GetExpectedTokensWithinCurrentRule() { ATN atn = Interpreter.atn; ATNState s = atn.states[State]; return(atn.NextTokens(s)); }
/// <summary> /// This method implements the single-token insertion inline error recovery /// strategy. /// </summary> /// <remarks> /// This method implements the single-token insertion inline error recovery /// strategy. It is called by /// <see cref="RecoverInline(Parser)"/> /// if the single-token /// deletion strategy fails to recover from the mismatched input. If this /// method returns /// <see langword="true"/> /// , /// <paramref name="recognizer"/> /// will be in error recovery /// mode. /// <p>This method determines whether or not single-token insertion is viable by /// checking if the /// <c>LA(1)</c> /// input symbol could be successfully matched /// if it were instead the /// <c>LA(2)</c> /// symbol. If this method returns /// <see langword="true"/> /// , the caller is responsible for creating and inserting a /// token with the correct type to produce this behavior.</p> /// </remarks> /// <param name="recognizer">the parser instance</param> /// <returns> /// /// <see langword="true"/> /// if single-token insertion is a viable recovery /// strategy for the current mismatched input, otherwise /// <see langword="false"/> /// </returns> protected internal virtual bool SingleTokenInsertion(Parser recognizer) { int currentSymbolType = ((ITokenStream)recognizer.InputStream).LA(1); // if current token is consistent with what could come after current // ATN state, then we know we're missing a token; error recovery // is free to conjure up and insert the missing token ATNState currentState = recognizer.Interpreter.atn.states[recognizer.State]; ATNState next = currentState.Transition(0).target; ATN atn = recognizer.Interpreter.atn; IntervalSet expectingAtLL2 = atn.NextTokens(next, recognizer.RuleContext); if (expectingAtLL2.Contains(currentSymbolType)) { ReportMissingToken(recognizer); return(true); } return(false); }
/// <summary> /// This method implements the single-token insertion inline error recovery /// strategy. /// </summary> /// <remarks> /// This method implements the single-token insertion inline error recovery /// strategy. It is called by /// <see cref="RecoverInline(Parser)"/> /// if the single-token /// deletion strategy fails to recover from the mismatched input. If this /// method returns /// <see langword="true"/> /// , /// <paramref name="recognizer"/> /// will be in error recovery /// mode. /// <p>This method determines whether or not single-token insertion is viable by /// checking if the /// <c>LA(1)</c> /// input symbol could be successfully matched /// if it were instead the /// <c>LA(2)</c> /// symbol. If this method returns /// <see langword="true"/> /// , the caller is responsible for creating and inserting a /// token with the correct type to produce this behavior.</p> /// </remarks> /// <param name="recognizer">the parser instance</param> /// <returns> /// /// <see langword="true"/> /// if single-token insertion is a viable recovery /// strategy for the current mismatched input, otherwise /// <see langword="false"/> /// </returns> protected internal virtual bool SingleTokenInsertion([NotNull] Parser recognizer) { int currentSymbolType = ((ITokenStream)recognizer.InputStream).La(1); // if current token is consistent with what could come after current // ATN state, then we know we're missing a token; error recovery // is free to conjure up and insert the missing token ATNState currentState = recognizer.Interpreter.atn.states[recognizer.State]; ATNState next = currentState.Transition(0).target; ATN atn = recognizer.Interpreter.atn; IntervalSet expectingAtLL2 = atn.NextTokens(next, PredictionContext.FromRuleContext(atn, recognizer._ctx)); // System.out.println("LT(2) set="+expectingAtLL2.toString(recognizer.getTokenNames())); if (expectingAtLL2.Contains(currentSymbolType)) { ReportMissingToken(recognizer); return(true); } return(false); }
protected internal virtual IntervalSet GetErrorRecoverySet(Parser recognizer) { ATN atn = recognizer.Interpreter.atn; RuleContext ctx = recognizer.RuleContext; IntervalSet recoverSet = new IntervalSet(); while (ctx != null && ctx.invokingState >= 0) { // compute what follows who invoked us ATNState invokingState = atn.states[ctx.invokingState]; RuleTransition rt = (RuleTransition)invokingState.Transition(0); IntervalSet follow = atn.NextTokens(rt.followState); recoverSet.AddAll(follow); ctx = ctx.Parent; } recoverSet.Remove(TokenConstants.Epsilon); // System.out.println("recover set "+recoverSet.toString(recognizer.getTokenNames())); return(recoverSet); }