public virtual PredictionContext GetChild(PredictionContext context, int invokingState) { if (!enableCache) { return(context.GetChild(invokingState)); } PredictionContextCache.PredictionContextAndInt operands = new PredictionContextCache.PredictionContextAndInt(context, invokingState); PredictionContext result; if (!childContexts.TryGetValue(operands, out result)) { result = context.GetChild(invokingState); result = GetAsCached(result); childContexts[operands] = result; } return(result); }
public static PredictionContext FromRuleContext(ATN atn, RuleContext outerContext) { if (outerContext == null) { outerContext = ParserRuleContext.EMPTY; } if (outerContext.Parent == null || outerContext == ParserRuleContext.EMPTY) { return(PredictionContext.EMPTY); } PredictionContext parent = PredictionContext.FromRuleContext(atn, outerContext.Parent); ATNState state = atn.states[outerContext.invokingState]; RuleTransition transition = (RuleTransition)state.Transition(0); return(parent.GetChild(transition.followState.stateNumber)); }
internal static Antlr4.Runtime.Atn.PredictionContext Join(Antlr4.Runtime.Atn.PredictionContext context0, Antlr4.Runtime.Atn.PredictionContext context1, PredictionContextCache contextCache) { if (context0 == context1) { return(context0); } if (context0.IsEmpty) { return(IsEmptyLocal(context0) ? context0 : AddEmptyContext(context1)); } else { if (context1.IsEmpty) { return(IsEmptyLocal(context1) ? context1 : AddEmptyContext(context0)); } } int context0size = context0.Size; int context1size = context1.Size; if (context0size == 1 && context1size == 1 && context0.GetReturnState(0) == context1 .GetReturnState(0)) { Antlr4.Runtime.Atn.PredictionContext merged = contextCache.Join(context0.GetParent (0), context1.GetParent(0)); if (merged == context0.GetParent(0)) { return(context0); } else { if (merged == context1.GetParent(0)) { return(context1); } else { return(merged.GetChild(context0.GetReturnState(0))); } } } int count = 0; Antlr4.Runtime.Atn.PredictionContext[] parentsList = new Antlr4.Runtime.Atn.PredictionContext [context0size + context1size]; int[] returnStatesList = new int[parentsList.Length]; int leftIndex = 0; int rightIndex = 0; bool canReturnLeft = true; bool canReturnRight = true; while (leftIndex < context0size && rightIndex < context1size) { if (context0.GetReturnState(leftIndex) == context1.GetReturnState(rightIndex)) { parentsList[count] = contextCache.Join(context0.GetParent(leftIndex), context1.GetParent (rightIndex)); returnStatesList[count] = context0.GetReturnState(leftIndex); canReturnLeft = canReturnLeft && parentsList[count] == context0.GetParent(leftIndex ); canReturnRight = canReturnRight && parentsList[count] == context1.GetParent(rightIndex ); leftIndex++; rightIndex++; } else { if (context0.GetReturnState(leftIndex) < context1.GetReturnState(rightIndex)) { parentsList[count] = context0.GetParent(leftIndex); returnStatesList[count] = context0.GetReturnState(leftIndex); canReturnRight = false; leftIndex++; } else { System.Diagnostics.Debug.Assert(context1.GetReturnState(rightIndex) < context0.GetReturnState (leftIndex)); parentsList[count] = context1.GetParent(rightIndex); returnStatesList[count] = context1.GetReturnState(rightIndex); canReturnLeft = false; rightIndex++; } } count++; } while (leftIndex < context0size) { parentsList[count] = context0.GetParent(leftIndex); returnStatesList[count] = context0.GetReturnState(leftIndex); leftIndex++; canReturnRight = false; count++; } while (rightIndex < context1size) { parentsList[count] = context1.GetParent(rightIndex); returnStatesList[count] = context1.GetReturnState(rightIndex); rightIndex++; canReturnLeft = false; count++; } if (canReturnLeft) { return(context0); } else { if (canReturnRight) { return(context1); } } if (count < parentsList.Length) { parentsList = Arrays.CopyOf(parentsList, count); returnStatesList = Arrays.CopyOf(returnStatesList, count); } if (parentsList.Length == 0) { // if one of them was EMPTY_LOCAL, it would be empty and handled at the beginning of the method return(EmptyFull); } else { if (parentsList.Length == 1) { return(new SingletonPredictionContext(parentsList[0], returnStatesList[0])); } else { return(new ArrayPredictionContext(parentsList, returnStatesList)); } } }
/// <summary> /// Compute set of tokens that can follow /// <code>s</code> /// in the ATN in the /// specified /// <code>ctx</code> /// . /// <p/> /// If /// <code>ctx</code> /// is /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see> /// and /// <code>stopState</code> /// or the end of the rule containing /// <code>s</code> /// is reached, /// <see cref="TokenConstants.Epsilon"/> /// is added to the result set. If /// <code>ctx</code> /// is not /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see> /// and /// <code>addEOF</code> /// is /// <code>true</code> /// and /// <code>stopState</code> /// or the end of the outermost rule is reached, /// <see cref="TokenConstants.Eof"/> /// is added to the result set. /// </summary> /// <param name="s">the ATN state.</param> /// <param name="stopState"> /// the ATN state to stop at. This can be a /// <see cref="BlockEndState">BlockEndState</see> /// to detect epsilon paths through a closure. /// </param> /// <param name="ctx"> /// The outer context, or /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see> /// if /// the outer context should not be used. /// </param> /// <param name="look">The result lookahead set.</param> /// <param name="lookBusy"> /// A set used for preventing epsilon closures in the ATN /// from causing a stack overflow. Outside code should pass /// <code>new HashSet<ATNConfig></code> /// for this argument. /// </param> /// <param name="calledRuleStack"> /// A set used for preventing left recursion in the /// ATN from causing a stack overflow. Outside code should pass /// <code>new BitSet()</code> /// for this argument. /// </param> /// <param name="seeThruPreds"> /// /// <code>true</code> /// to true semantic predicates as /// implicitly /// <code>true</code> /// and "see through them", otherwise /// <code>false</code> /// to treat semantic predicates as opaque and add /// <see cref="HitPred">HitPred</see> /// to the /// result if one is encountered. /// </param> /// <param name="addEOF"> /// Add /// <see cref="TokenConstants.Eof"/> /// to the result if the end of the /// outermost context is reached. This parameter has no effect if /// <code>ctx</code> /// is /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see> /// . /// </param> protected internal virtual void Look(ATNState s, ATNState stopState, PredictionContext ctx, IntervalSet look, HashSet <ATNConfig> lookBusy, BitSet calledRuleStack, bool seeThruPreds, bool addEOF) { // System.out.println("_LOOK("+s.stateNumber+", ctx="+ctx); ATNConfig c = ATNConfig.Create(s, 0, ctx); if (!lookBusy.Add(c)) { return; } if (s == stopState) { if (PredictionContext.IsEmptyLocal(ctx)) { look.Add(TokenConstants.Epsilon); return; } else { if (ctx.IsEmpty && addEOF) { look.Add(TokenConstants.Eof); return; } } } if (s is RuleStopState) { if (PredictionContext.IsEmptyLocal(ctx)) { look.Add(TokenConstants.Epsilon); return; } else { if (ctx.IsEmpty && addEOF) { look.Add(TokenConstants.Eof); return; } } for (int i = 0; i < ctx.Size; i++) { if (ctx.GetReturnState(i) != PredictionContext.EmptyFullStateKey) { ATNState returnState = atn.states[ctx.GetReturnState(i)]; // System.out.println("popping back to "+retState); for (int j = 0; j < ctx.Size; j++) { bool removed = calledRuleStack.Get(returnState.ruleIndex); try { calledRuleStack.Clear(returnState.ruleIndex); Look(returnState, stopState, ctx.GetParent(j), look, lookBusy, calledRuleStack, seeThruPreds , addEOF); } finally { if (removed) { calledRuleStack.Set(returnState.ruleIndex); } } } return; } } } int n = s.NumberOfTransitions; for (int i_1 = 0; i_1 < n; i_1++) { Transition t = s.Transition(i_1); if (t.GetType() == typeof(RuleTransition)) { if (calledRuleStack.Get(((RuleTransition)t).target.ruleIndex)) { continue; } PredictionContext newContext = ctx.GetChild(((RuleTransition)t).followState.stateNumber ); try { calledRuleStack.Set(((RuleTransition)t).target.ruleIndex); Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds , addEOF); } finally { calledRuleStack.Clear(((RuleTransition)t).target.ruleIndex); } } else { if (t is AbstractPredicateTransition) { if (seeThruPreds) { Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF ); } else { look.Add(HitPred); } } else { if (t.IsEpsilon) { Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF ); } else { if (t.GetType() == typeof(WildcardTransition)) { look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType)); } else { // System.out.println("adding "+ t); IntervalSet set = t.Label; if (set != null) { if (t is NotSetTransition) { set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType )); } look.AddAll(set); } } } } } } }