public void TestComplement2() { IntervalSet s = IntervalSet.Of(100, 101); IntervalSet s2 = IntervalSet.Of(100, 102); String expecting = "102"; String result = (s.Complement(s2)).ToString(); Assert.AreEqual(expecting, result); }
public void TestNotSetEdgeElement() { IntervalSet vocabulary = IntervalSet.Of(1, 2); IntervalSet s = IntervalSet.Of(1); String expecting = "2"; String result = (s.Complement(vocabulary)).ToString(); Assert.AreEqual(expecting, result); }
public void TestComplement3() { IntervalSet s = IntervalSet.Of(1, 96); s.Add(99, Lexer.MaxCharValue); String expecting = "{97..98}"; String result = (s.Complement(1, Lexer.MaxCharValue)).ToString(); Assert.AreEqual(expecting, result); }
public void TestNotSingleElement() { IntervalSet vocabulary = IntervalSet.Of(1, 1000); vocabulary.Add(2000, 3000); IntervalSet s = IntervalSet.Of(50, 50); String expecting = "{1..49, 51..1000, 2000..3000}"; String result = (s.Complement(vocabulary)).ToString(); Assert.AreEqual(expecting, result); }
public void TestNotSet() { IntervalSet vocabulary = IntervalSet.Of(1, 1000); IntervalSet s = IntervalSet.Of(50, 60); s.Add(5); s.Add(250, 300); String expecting = "{1..4, 6..49, 61..249, 301..1000}"; String result = (s.Complement(vocabulary)).ToString(); Assert.AreEqual(expecting, result); }
public void TestNotSetFragmentedVocabulary() { IntervalSet vocabulary = IntervalSet.Of(1, 255); vocabulary.Add(1000, 2000); vocabulary.Add(9999); IntervalSet s = IntervalSet.Of(50, 60); s.Add(3); s.Add(250, 300); s.Add(10000); // this is outside range of vocab and should be ignored String expecting = "{1..2, 4..49, 61..249, 1000..2000, 9999}"; String result = (s.Complement(vocabulary)).ToString(); Assert.AreEqual(expecting, result); }
private bool Validate(List <Edge> parse, List <IToken> i) { List <Edge> q = parse.ToList(); q.Reverse(); List <IToken> .Enumerator ei = _input.GetEnumerator(); List <Edge> .Enumerator eq = q.GetEnumerator(); bool fei = false; bool feq = false; for (; ;) { fei = ei.MoveNext(); IToken v = ei.Current; if (!fei) { break; } bool empty = true; for (; empty;) { feq = eq.MoveNext(); if (!feq) { break; } Edge x = eq.Current; switch (x._type) { case TransitionType.RULE: empty = true; break; case TransitionType.PREDICATE: empty = true; break; case TransitionType.ACTION: empty = true; break; case TransitionType.ATOM: empty = false; break; case TransitionType.EPSILON: empty = true; break; case TransitionType.INVALID: empty = true; break; case TransitionType.NOT_SET: empty = false; break; case TransitionType.PRECEDENCE: empty = true; break; case TransitionType.SET: empty = false; break; case TransitionType.WILDCARD: empty = false; break; default: throw new Exception(); } } Edge w = eq.Current; if (w == null && v == null) { return(true); } else if (w == null) { return(false); } else if (v == null) { return(false); } switch (w._type) { case TransitionType.ATOM: { IntervalSet set = w._label; if (set != null && set.Count > 0) { if (!set.Contains(v.Type)) { return(false); } } break; } case TransitionType.NOT_SET: { IntervalSet set = w._label; set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, _parser.Atn.maxTokenType)); if (set != null && set.Count > 0) { if (!set.Contains(v.Type)) { return(false); } } break; } case TransitionType.SET: { IntervalSet set = w._label; if (set != null && set.Count > 0) { if (!set.Contains(v.Type)) { return(false); } } break; } case TransitionType.WILDCARD: break; default: throw new Exception(); } } return(true); }
// Step to state and continue parsing input. // Returns a list of transitions leading to a state that accepts input. private List <List <Edge> > EnterState(Edge t) { int here = ++entry_value; int index_on_transition = t._index_at_transition; int token_index = t._index; ATNState state = t._to; IToken input_token = _input[token_index]; if (_log_parse) { System.Console.Error.WriteLine("Entry " + here + " State " + state + " tokenIndex " + token_index + " " + input_token.Text ); } // Upon reaching the cursor, return match. bool at_match = input_token.TokenIndex >= _cursor; if (at_match) { if (_log_parse) { System.Console.Error.Write("Entry " + here + " return "); } List <List <Edge> > res = new List <List <Edge> >() { new List <Edge>() { t } }; if (_log_parse) { string str = PrintResult(res); System.Console.Error.WriteLine(str); } return(res); } if (_visited.ContainsKey(new Pair <ATNState, int>(state, token_index))) { return(null); } _visited[new Pair <ATNState, int>(state, token_index)] = true; List <List <Edge> > result = new List <List <Edge> >(); if (_stop_states.Contains(state)) { if (_log_parse) { System.Console.Error.Write("Entry " + here + " return "); } List <List <Edge> > res = new List <List <Edge> >() { new List <Edge>() { t } }; if (_log_parse) { string str = PrintResult(res); System.Console.Error.WriteLine(str); } return(res); } // Search all transitions from state. foreach (Transition transition in state.TransitionsArray) { List <List <Edge> > matches = null; switch (transition.TransitionType) { case TransitionType.RULE: { RuleTransition rule = (RuleTransition)transition; ATNState sub_state = rule.target; matches = EnterState(new Edge() { _from = state, _to = rule.target, _follow = rule.followState, _label = rule.Label, _type = rule.TransitionType, _index = token_index, _index_at_transition = token_index }); if (matches != null && matches.Count == 0) { throw new Exception(); } if (matches != null) { List <List <Edge> > new_matches = new List <List <Edge> >(); foreach (List <Edge> match in matches) { Edge f = match.First(); // "to" is possibly final state of submachine. Edge l = match.Last(); // "to" is start state of submachine. bool is_final = _stop_states.Contains(f._to); bool is_at_caret = f._index >= _cursor; if (!is_final) { new_matches.Add(match); } else { List <List <Edge> > xxx = EnterState(new Edge() { _from = f._to, _to = rule.followState, _label = null, _type = TransitionType.EPSILON, _index = f._index, _index_at_transition = f._index }); if (xxx != null && xxx.Count == 0) { throw new Exception(); } if (xxx != null) { foreach (List <Edge> y in xxx) { List <Edge> copy = y.ToList(); foreach (Edge q in match) { copy.Add(q); } new_matches.Add(copy); } } } } matches = new_matches; } } break; case TransitionType.PREDICATE: if (CheckPredicate((PredicateTransition)transition)) { matches = EnterState(new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index, _index_at_transition = token_index }); if (matches != null && matches.Count == 0) { throw new Exception(); } } break; case TransitionType.WILDCARD: matches = EnterState(new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index + 1, _index_at_transition = token_index }); if (matches != null && matches.Count == 0) { throw new Exception(); } break; default: if (transition.IsEpsilon) { matches = EnterState(new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index, _index_at_transition = token_index }); if (matches != null && matches.Count == 0) { throw new Exception(); } } else { IntervalSet set = transition.Label; if (set != null && set.Count > 0) { if (transition.TransitionType == TransitionType.NOT_SET) { set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, _parser.Atn.maxTokenType)); } if (set.Contains(input_token.Type)) { matches = EnterState(new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index + 1, _index_at_transition = token_index }); if (matches != null && matches.Count == 0) { throw new Exception(); } } } } break; } if (matches != null) { foreach (List <Edge> match in matches) { List <Edge> x = match.ToList(); if (t != null) { x.Add(t); Edge prev = null; foreach (Edge z in x) { ATNState ff = z._to; if (prev != null) { if (prev._from != ff) { System.Console.Error.WriteLine("Fail " + PrintSingle(x)); Debug.Assert(false); } } prev = z; } } result.Add(x); } } } if (result.Count == 0) { return(null); } if (_log_parse) { System.Console.Error.Write("Entry " + here + " return "); string str = PrintResult(result); System.Console.Error.WriteLine(str); } return(result); }
// Step to state and continue parsing input. // Returns a list of transitions leading to a state that accepts input. private List <List <Edge> > EnterState(List <int> p, Edge t, int indent) { int here = ++entry_value; int index_on_transition = t._index_at_transition; int token_index = t._index; ATNState state = t._to; var rule_match = _parser.Atn.ruleToStartState.Where(v => v.stateNumber == state.stateNumber); var start_rule = rule_match.Any() ? rule_match.FirstOrDefault().ruleIndex : -1; var q = p.ToList(); if (start_rule >= 0) { q.Add(start_rule); } // Upon reaching the cursor, return match. bool at_match = token_index == _cursor; if (at_match) { if (_log_parse) { System.Console.Error.Write( new String(' ', indent * 2) + "Entry " + here + " return "); } List <List <Edge> > res = new List <List <Edge> >() { new List <Edge>() { t } }; if (_log_parse) { string str = PrintResult(res); System.Console.Error.WriteLine( str); } return(res); } IToken input_token = _input[token_index]; if (_log_parse) { var name = (start_rule >= 0) ? (" " + _parser.RuleNames[start_rule]) : ""; System.Console.Error.WriteLine( new String(' ', indent * 2) + "Entry " + here + " State " + state + name + " tokenIndex " + token_index + " " + input_token.Text ); } bool at_match2 = input_token.TokenIndex >= _cursor; if (at_match2) { if (_log_parse) { System.Console.Error.Write( new String(' ', indent * 2) + "Entry " + here + " return "); } List <List <Edge> > res = new List <List <Edge> >() { new List <Edge>() { t } }; if (_log_parse) { string str = PrintResult(res); System.Console.Error.WriteLine( str); } return(res); } if (_visited.ContainsKey(new Tuple <ATNState, int, int>(state, token_index, indent))) { if (_visited_extra.ContainsKey(new Tuple <ATNState, int, int, List <int> >( state, token_index, indent, p))) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "already visited."); } return(null); } } _visited_extra[new Tuple <ATNState, int, int, List <int> >(state, token_index, indent, q)] = true; _visited[new Tuple <ATNState, int, int>(state, token_index, indent)] = true; List <List <Edge> > result = new List <List <Edge> >(); if (_stop_states.Contains(state)) { if (_log_parse) { var n = _parser.Atn.ruleToStartState.Where(v => v.stateNumber == state.stateNumber); var r = n.Any() ? n.FirstOrDefault().ruleIndex : -1; var name = (r >= 0) ? (" " + _parser.RuleNames[r]) : ""; System.Console.Error.Write( new String(' ', indent * 2) + "Entry " + here + " State " + state + name + " tokenIndex " + token_index + " " + input_token.Text + " return "); } List <List <Edge> > res = new List <List <Edge> >() { new List <Edge>() { t } }; if (_log_parse) { string str = PrintResult(res); System.Console.Error.WriteLine( str); } return(res); } // Search all transitions from state. foreach (Transition transition in state.TransitionsArray) { List <List <Edge> > matches = null; switch (transition.TransitionType) { case TransitionType.RULE: { RuleTransition rule = (RuleTransition)transition; ATNState sub_state = rule.target; matches = EnterState(q, new Edge() { _from = state, _to = rule.target, _follow = rule.followState, _label = rule.Label, _type = rule.TransitionType, _index = token_index, _index_at_transition = token_index }, indent + 1); if (matches != null && matches.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } if (matches != null) { List <List <Edge> > new_matches = new List <List <Edge> >(); foreach (List <Edge> match in matches) { Edge f = match.First(); // "to" is possibly final state of submachine. Edge l = match.Last(); // "to" is start state of submachine. bool is_final = _stop_states.Contains(f._to); bool is_at_caret = f._index >= _cursor; if (!is_final) { new_matches.Add(match); } else { List <List <Edge> > xxx = EnterState(q, new Edge() { _from = f._to, _to = rule.followState, _label = null, _type = TransitionType.EPSILON, _index = f._index, _index_at_transition = f._index }, indent + 1); if (xxx != null && xxx.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } if (xxx != null) { foreach (List <Edge> y in xxx) { List <Edge> copy = y.ToList(); foreach (Edge g in match) { copy.Add(g); } new_matches.Add(copy); } } } } matches = new_matches; } } break; case TransitionType.PREDICATE: if (CheckPredicate((PredicateTransition)transition)) { matches = EnterState(q, new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index, _index_at_transition = token_index }, indent + 1); if (matches != null && matches.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } } break; case TransitionType.WILDCARD: matches = EnterState(q, new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index + 1, _index_at_transition = token_index }, indent + 1); if (matches != null && matches.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } break; default: if (transition.IsEpsilon) { matches = EnterState(q, new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index, _index_at_transition = token_index }, indent + 1); if (matches != null && matches.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } } else { IntervalSet set = transition.Label; if (set != null && set.Count > 0) { if (transition.TransitionType == TransitionType.NOT_SET) { set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, _parser.Atn.maxTokenType)); } if (set.Contains(input_token.Type)) { matches = EnterState(q, new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index + 1, _index_at_transition = token_index }, indent + 1); if (matches != null && matches.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } } } } break; } if (matches != null) { foreach (List <Edge> match in matches) { List <Edge> x = match.ToList(); if (t != null) { x.Add(t); Edge prev = null; foreach (Edge z in x) { ATNState ff = z._to; if (prev != null) { if (prev._from != ff) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "Fail " + PrintSingle(x)); Debug.Assert(false); } } prev = z; } } result.Add(x); } } } if (result.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "result empty."); } return(null); } if (_log_parse) { var n = _parser.Atn.ruleToStartState.Where(v => v.stateNumber == state.stateNumber); var r = n.Any() ? n.FirstOrDefault().ruleIndex : -1; var name = (r >= 0) ? (" " + _parser.RuleNames[r]) : ""; System.Console.Error.Write( new String(' ', indent * 2) + "Entry " + here + " State " + state + name + " tokenIndex " + token_index + " " + input_token.Text + " return "); string str = PrintResult(result); System.Console.Error.WriteLine( str); } return(result); }
/// <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); } } } } } } }
/// <summary> /// Compute set of tokens that can follow /// <paramref name="s"/> /// in the ATN in the /// specified /// <paramref name="ctx"/> /// . /// <p/> /// If /// <paramref name="ctx"/> /// is /// <see cref="PredictionContext.EmptyLocal"/> /// and /// <paramref name="stopState"/> /// or the end of the rule containing /// <paramref name="s"/> /// is reached, /// <see cref="TokenConstants.EPSILON"/> /// is added to the result set. If /// <paramref name="ctx"/> /// is not /// <see cref="PredictionContext.EmptyLocal"/> /// and /// <paramref name="addEOF"/> /// is /// <see langword="true"/> /// and /// <paramref name="stopState"/> /// 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"/> /// to detect epsilon paths through a closure. /// </param> /// <param name="ctx"> /// The outer context, or /// <see cref="PredictionContext.EmptyLocal"/> /// 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 /// <c>new HashSet<ATNConfig></c> /// 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 /// <c>new BitSet()</c> /// for this argument. /// </param> /// <param name="seeThruPreds"> /// /// <see langword="true"/> /// to true semantic predicates as /// implicitly /// <see langword="true"/> /// and "see through them", otherwise /// <see langword="false"/> /// to treat semantic predicates as opaque and add /// <see cref="HitPred"/> /// 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 /// <paramref name="ctx"/> /// is /// <see cref="PredictionContext.EmptyLocal"/> /// . /// </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 = new ATNConfig(s, 0, ctx); if (!lookBusy.Add(c)) { return; } if (s == stopState) { if (ctx == null) { look.Add(TokenConstants.EPSILON); return; } else if (ctx.IsEmpty && addEOF) { look.Add(TokenConstants.EOF); return; } } if (s is RuleStopState) { if (ctx == null) { look.Add(TokenConstants.EPSILON); return; } else if (ctx.IsEmpty && addEOF) { look.Add(TokenConstants.EOF); return; } if (ctx != PredictionContext.EMPTY) { for (int i = 0; i < ctx.Size; i++) { ATNState returnState = atn.states[ctx.GetReturnState(i)]; bool removed = calledRuleStack.Get(returnState.ruleIndex); try { calledRuleStack.Clear(returnState.ruleIndex); Look(returnState, stopState, ctx.GetParent(i), 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 is RuleTransition) { RuleTransition ruleTransition = (RuleTransition)t; if (calledRuleStack.Get(ruleTransition.ruleIndex)) { continue; } PredictionContext newContext = SingletonPredictionContext.Create(ctx, ruleTransition.followState.stateNumber); try { calledRuleStack.Set(ruleTransition.target.ruleIndex); Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF); } finally { calledRuleStack.Clear(ruleTransition.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 is WildcardTransition) { look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType)); } else { IntervalSet set = t.Label; if (set != null) { if (t is NotSetTransition) { set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType)); } look.AddAll(set); } } } } } } }