protected ATNConfig PredTransition(ATNConfig config,
PredicateTransition pt,
bool collectPredicates,
bool inContext,
bool fullCtx)
{
if (debug)
{
Console.WriteLine("PRED (collectPredicates=" + collectPredicates + ") " +
pt.ruleIndex + ":" + pt.predIndex +
", ctx dependent=" + pt.isCtxDependent);
if (parser != null)
{
Console.WriteLine("context surrounding pred is " +
parser.GetRuleInvocationStack());
}
}
ATNConfig c = null;
if (collectPredicates &&
(!pt.isCtxDependent || (pt.isCtxDependent && inContext)))
{
if (fullCtx)
{
// In full context mode, we can evaluate predicates on-the-fly
// during closure, which dramatically reduces the size of
// the config sets. It also obviates the need to test predicates
// later during conflict resolution.
int currentPosition = input.Index;
input.Seek(startIndex);
bool predSucceeds = EvalSemanticContext(pt.Predicate, context, config.alt, fullCtx);
input.Seek(currentPosition);
if (predSucceeds)
{
c = new ATNConfig(config, pt.target); // no pred context
}
}
else {
SemanticContext newSemCtx = SemanticContext.AndOp(config.semanticContext, pt.Predicate);
c = new ATNConfig(config, pt.target, newSemCtx);
}
}
else {
c = new ATNConfig(config, pt.target);
}
if (debug) Console.WriteLine("config from pred transition=" + c);
return c;
}