/// <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, PredictionContext.FromRuleContext(atn, recognizer.RuleContext)); // System.out.println("LT(2) set="+expectingAtLL2.toString(recognizer.getTokenNames())); if (expectingAtLL2.Contains(currentSymbolType)) { ReportMissingToken(recognizer); return(true); } return(false); }
public override IToken RecoverInline(Parser recognizer) { if (recognizer is ICodeCompletionParser && ((ITokenStream)recognizer.InputStream).Lt(1) is ICaretToken) { ICodeCompletionParser parser = (ICodeCompletionParser)recognizer; ICaretToken token = (ICaretToken)((ITokenStream)recognizer.InputStream).Lt(1); CompletionParserATNSimulator interp = parser.Interpreter; int stateNumber = recognizer.State; ATNState state = interp.atn.states[stateNumber]; PredictionContext context = PredictionContext.FromRuleContext(interp.atn, recognizer.Context, false); ATNConfigSet intermediate = new ATNConfigSet(); ATNConfigSet closure = new ATNConfigSet(); for (int i = 0; i < state.NumberOfTransitions; i++) { Transition transition = state.Transition(i); if (transition.IsEpsilon) { ATNState target = transition.target; ATNConfig config = ATNConfig.Create(target, i + 1, context); intermediate.Add(config); } } bool collectPredicates = false; bool hasMoreContext = true; interp.ClosureHelper(intermediate, closure, collectPredicates, hasMoreContext, PredictionContextCache.Uncached, false); if (!state.OnlyHasEpsilonTransitions) { for (int i = 0; i < state.NumberOfTransitions; i++) { closure.Add(ATNConfig.Create(state, i + 1, PredictionContext.FromRuleContext(interp.atn, recognizer.Context))); } } Dictionary <ATNConfig, IList <Transition> > transitions = null; int ncl = closure.Count; // TODO: foreach for (int ci = 0; ci < ncl; ci++) { ATNConfig c = closure[ci]; List <Transition> configTransitions = null; int n = c.State.NumberOfTransitions; for (int ti = 0; ti < n; ti++) { // for each transition Transition trans = c.State.Transition(ti); ATNState target = interp.GetReachableTargetHelper(c, trans, CaretToken.CaretTokenType); if (target != null) { if (transitions == null) { transitions = new Dictionary <ATNConfig, IList <Transition> >(); } if (configTransitions == null) { configTransitions = new List <Transition>(); transitions[c] = configTransitions; } configTransitions.Add(trans); } } } /* * This should be null if the intended token is not "wordlike", and * should be a single transition from the current state. */ if (transitions != null) { Debug.Assert(transitions.Count == 1); Debug.Assert(transitions.Values.First().Count == 1); Debug.Assert(state.NumberOfTransitions == 1); Debug.Assert(transitions.Values.First()[0] == state.Transition(0)); } throw new CaretReachedException(parser.Context, token, transitions, null); } return(base.RecoverInline(recognizer)); }