public static IList<ParserRuleContext> GetLookaheadParseTrees(Grammar g,
ParserInterpreter originalParser,
ITokenStream tokens,
int startRuleIndex,
int decision,
int startIndex,
int stopIndex)
{
IList<ParserRuleContext> trees = new List<ParserRuleContext>();
// Create a new parser interpreter to parse the ambiguous subphrase
ParserInterpreter parser = DeriveTempParserInterpreter(g, originalParser, tokens);
DecisionState decisionState = originalParser.Atn.decisionToState[decision];
for (int alt = 1; alt <= decisionState.Transitions.Length; alt++)
{
// re-parse entire input for all ambiguous alternatives
// (don't have to do first as it's been parsed, but do again for simplicity
// using this temp parser.)
BailButConsumeErrorStrategy errorHandler = new BailButConsumeErrorStrategy();
parser.ErrorHandler = errorHandler;
parser.Reset();
parser.AddDecisionOverride(decision, startIndex, alt);
ParserRuleContext tt = parser.Parse(startRuleIndex);
int stopTreeAt = stopIndex;
if (errorHandler.firstErrorTokenIndex >= 0)
{
stopTreeAt = errorHandler.firstErrorTokenIndex; // cut off rest at first error
}
Interval overallRange = tt.SourceInterval;
if (stopTreeAt > overallRange.b)
{
// If we try to look beyond range of tree, stopTreeAt must be EOF
// for which there is no EOF ref in grammar. That means tree
// will not have node for stopTreeAt; limit to overallRange.b
stopTreeAt = overallRange.b;
}
ParserRuleContext subtree =
Trees.GetRootOfSubtreeEnclosingRegion(tt,
startIndex,
stopTreeAt);
// Use higher of overridden decision tree or tree enclosing all tokens
if (Trees.IsAncestorOf(parser.OverrideDecisionRoot, subtree))
{
subtree = parser.OverrideDecisionRoot;
}
Trees.StripChildrenOutOfRange(subtree, parser.OverrideDecisionRoot, startIndex, stopTreeAt);
trees.Add(subtree);
}
return trees;
}