in Microsoft.Azure.Cosmos/src/Query/Core/Parser/LASets.cs [495:606]
private HashSet<ATNState> ComputeSingle(List<Edge> parse)
{
List<Edge> copy = parse.ToList();
HashSet<ATNState> result = new HashSet<ATNState>();
if (this.logClosure)
{
System.Console.Error.WriteLine("Computing closure for the following parse:");
System.Console.Error.Write(this.PrintSingle(parse));
System.Console.Error.WriteLine();
}
if (!copy.Any())
{
return result;
}
Edge last_transaction = copy.First();
if (last_transaction == null)
{
return result;
}
ATNState current_state = last_transaction.to;
if (current_state == null)
{
throw new Exception();
}
for (; ; )
{
if (this.logClosure)
{
System.Console.Error.WriteLine("Getting closure of " + current_state.stateNumber);
}
HashSet<ATNState> c = this.closure(current_state);
if (this.logClosure)
{
System.Console.Error.WriteLine("closure " + string.Join(" ", c.Select(s => s.stateNumber)));
}
bool do_continue = false;
ATN atn = current_state.atn;
int rule = current_state.ruleIndex;
RuleStartState start_state = atn.ruleToStartState[rule];
RuleStopState stop_state = atn.ruleToStopState[rule];
bool changed = false;
foreach (ATNState s in c)
{
if (result.Contains(s))
{
continue;
}
changed = true;
result.Add(s);
if (s == stop_state)
{
do_continue = true;
}
}
if (!changed)
{
break;
}
if (!do_continue)
{
break;
}
for (; ; )
{
if (!copy.Any())
{
break;
}
copy.RemoveAt(0);
if (!copy.Any())
{
break;
}
last_transaction = copy.First();
if (start_state == last_transaction.from)
{
copy.RemoveAt(0);
if (!copy.Any())
{
break;
}
last_transaction = copy.First();
// Get follow state of rule-type transition.
ATNState from_state = last_transaction.from;
if (from_state == null)
{
break;
}
ATNState follow_state = last_transaction.follow;
current_state = follow_state;
if (current_state == null)
{
throw new Exception();
}
break;
}
}
}
return result;
}