diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java index 077e5650c..0265906a5 100755 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java @@ -1265,7 +1265,7 @@ public class ParserATNSimulator extends ATNSimulator { ATNConfigSet failed = new ATNConfigSet(configs.fullCtx); for (ATNConfig c : configs) { if ( c.semanticContext!=SemanticContext.NONE ) { - boolean predicateEvaluationResult = c.semanticContext.eval(parser, outerContext); + boolean predicateEvaluationResult = evalSemanticContext(c.semanticContext, outerContext, c.alt, configs.fullCtx); if ( predicateEvaluationResult ) { succeeded.add(c); } @@ -1287,8 +1287,8 @@ public class ParserATNSimulator extends ATNSimulator { * includes pairs with null predicates. */ protected BitSet evalSemanticContext(@NotNull DFAState.PredPrediction[] predPredictions, - ParserRuleContext outerContext, - boolean complete) + ParserRuleContext outerContext, + boolean complete) { BitSet predictions = new BitSet(); for (DFAState.PredPrediction pair : predPredictions) { @@ -1300,7 +1300,8 @@ public class ParserATNSimulator extends ATNSimulator { continue; } - boolean predicateEvaluationResult = pair.pred.eval(parser, outerContext); + boolean fullCtx = false; // in dfa + boolean predicateEvaluationResult = evalSemanticContext(pair.pred, outerContext, pair.alt, fullCtx); if ( debug || dfa_debug ) { System.out.println("eval pred "+pair+"="+predicateEvaluationResult); } @@ -1317,6 +1318,17 @@ public class ParserATNSimulator extends ATNSimulator { return predictions; } + /** Evaluate the predicate context using the indicated parser stack and return the result. + * The alt parameter indicates the predicted alternative but is used only by the profiler + * at the moment. The profiler wants to track whether or not this predicate evaluated + * in SLL or LL mode and so we pass in evalInFullCtx. + * + * All pred eval goes through here, even precedence preds, so we have a hook for profiling. + * Compiler should inline. + */ + protected boolean evalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, int alt, boolean fullCtx) { + return pred.eval(parser, parserCallStack); + } /* TODO: If we are doing predicates, there is no point in pursuing closure operations if we reach a DFA state that uniquely predicts @@ -1544,7 +1556,7 @@ public class ParserATNSimulator extends ATNSimulator { // later during conflict resolution. int currentPosition = _input.index(); _input.seek(_startIndex); - boolean predSucceeds = pt.getPredicate().eval(parser, _outerContext); + boolean predSucceeds = evalSemanticContext(pt.getPredicate(), _outerContext, config.alt, fullCtx); _input.seek(currentPosition); if ( predSucceeds ) { c = new ATNConfig(config, pt.target); // no pred context @@ -1592,7 +1604,7 @@ public class ParserATNSimulator extends ATNSimulator { // later during conflict resolution. int currentPosition = _input.index(); _input.seek(_startIndex); - boolean predSucceeds = pt.getPredicate().eval(parser, _outerContext); + boolean predSucceeds = evalSemanticContext(pt.getPredicate(), _outerContext, config.alt, fullCtx); _input.seek(currentPosition); if ( predSucceeds ) { c = new ATNConfig(config, pt.target); // no pred context @@ -1894,7 +1906,7 @@ public class ParserATNSimulator extends ATNSimulator { ", input="+parser.getTokenStream().getText(interval)); } if ( parser!=null ) parser.getErrorListenerDispatch().reportAmbiguity(parser, dfa, startIndex, stopIndex, - exact, ambigAlts, configs); + exact, ambigAlts, configs); } public final void setPredictionMode(@NotNull PredictionMode mode) { diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/PredicateEvalInfo.java b/runtime/Java/src/org/antlr/v4/runtime/atn/PredicateEvalInfo.java index b2bcaeba3..7abcfff11 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/PredicateEvalInfo.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/PredicateEvalInfo.java @@ -31,11 +31,8 @@ package org.antlr.v4.runtime.atn; import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.dfa.DFAState; import org.antlr.v4.runtime.misc.NotNull; -import java.util.BitSet; - /** * This class represents profiling event information for semantic predicate * evaluations which occur during prediction. @@ -43,53 +40,36 @@ import java.util.BitSet; * @see ParserATNSimulator#evalSemanticContext */ public class PredicateEvalInfo extends DecisionEventInfo { - /** - * The DFA state at which predicate evaluation is required in order to - * continue. - */ - public final DFAState dfaState; - /** - * The results of evaluating specific semantic contexts. The elements of - * this array correspond to the elements in {@link DFAState#predicates}, and - * the value of each element is the result of evaluating the semantic - * context {@link DFAState.PredPrediction#pred}. - */ - public final boolean[] evalResults; - /** - * A {@link BitSet} identifying the represented alternatives of - * {@link #dfaState} which remain viable following the evaluation of - * semantic predicates. - */ - public final BitSet predictions; + public final SemanticContext semctx; + public final int predictedAlt; + public final boolean evalResult; /** * Constructs a new instance of the {@link PredicateEvalInfo} class with the * specified detailed predicate evaluation information. * - * @param dfaState The DFA state containing information about the semantic - * predicates to evaluate during the prediction process * @param decision The decision number * @param input The input token stream * @param startIndex The start index for the current prediction * @param stopIndex The index at which the predicate evaluation was * triggered. Note that the input stream may be reset to other locations for * the actual evaluation of individual predicates. - * @param evalResults The results of evaluating specific semantic contexts. - * The elements of this array correspond to the elements in - * {@link DFAState#predicates}, and the value of each element is the result - * of evaluating the semantic context {@link DFAState.PredPrediction#pred}. - * @param predictions A {@link BitSet} identifying the represented - * alternatives of {@code dfaState} which remain viable following the - * evaluation of semantic predicates + * @param evalResult The results of evaluating the semantic context. + * @param predictedAlt Identifies the represented + * alternative of {@code decision} that remains viable following the + * evaluation of semantic predicates. + * @param requiresFullContext Indicate if pred evaluated during full context prediction. */ - public PredicateEvalInfo(@NotNull DFAState dfaState, int decision, + public PredicateEvalInfo(int decision, @NotNull TokenStream input, int startIndex, int stopIndex, - @NotNull boolean[] evalResults, - @NotNull BitSet predictions) + @NotNull SemanticContext semctx, + @NotNull boolean evalResult, + @NotNull int predictedAlt, + @NotNull boolean requiresFullContext) { - super(decision, dfaState.configs, input, startIndex, stopIndex, dfaState.requiresFullContext); - this.dfaState = dfaState; - this.evalResults = evalResults; - this.predictions = predictions; + super(decision, new ATNConfigSet(), input, startIndex, stopIndex, requiresFullContext); + this.semctx = semctx; + this.evalResult = evalResult; + this.predictedAlt = predictedAlt; } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ProfilingATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ProfilingATNSimulator.java index 3f4bc3b3e..3c4a09752 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ProfilingATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ProfilingATNSimulator.java @@ -162,40 +162,14 @@ public class ProfilingATNSimulator extends ParserATNSimulator { } @Override - protected BitSet evalSemanticContext(DFAState.PredPrediction[] predPredictions, - ParserRuleContext outerContext, - boolean complete) { - /* Force complete prediction for the purpose of gathering statistical - * results. If the caller requested incomplete evaluation, the result is - * modified before returning to behave as though incomplete evaluation - * was used. - */ - BitSet predictions = super.evalSemanticContext(predPredictions, outerContext, true); - // must re-evaluate all preds as predictions can't map back to pred eval uniquely - int n = predPredictions.length; - boolean[] results = new boolean[n]; - int i = 0; - // FOR INTERPRETER, these are all true unless precedence preds! - for (DFAState.PredPrediction pair : predPredictions) { - if ( pair.pred!=SemanticContext.NONE ) { - results[i] = pair.pred.eval(parser, outerContext); - } - i++; - } - + protected boolean evalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, int alt, boolean fullCtx) { + boolean result = super.evalSemanticContext(pred, parserCallStack, alt, fullCtx); boolean fullContext = _llStopIndex >= 0; int stopIndex = fullContext ? _llStopIndex : _sllStopIndex; decisions[currentDecision].predicateEvals.add( - new PredicateEvalInfo(currentState, currentDecision, _input, _startIndex, stopIndex, results, predictions) + new PredicateEvalInfo(currentDecision, _input, _startIndex, stopIndex, pred, result, alt, fullCtx) ); - - if (!complete && !predictions.isEmpty()) { - int minimum = predictions.nextSetBit(0); - predictions = new BitSet(); - predictions.set(minimum); - } - - return predictions; + return result; } @Override diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/SemanticContext.java b/runtime/Java/src/org/antlr/v4/runtime/atn/SemanticContext.java index ac9c53aae..31141841b 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/SemanticContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/SemanticContext.java @@ -72,13 +72,13 @@ public abstract class SemanticContext { * prediction, so we passed in the outer context here in case of context * dependent predicate evaluation.

*/ - public abstract boolean eval(Recognizer parser, RuleContext outerContext); + public abstract boolean eval(Recognizer parser, RuleContext parserCallStack); /** * Evaluate the precedence predicates for the context and reduce the result. * * @param parser The parser instance. - * @param outerContext The current parser context object. + * @param parserCallStack * @return The simplified semantic context after precedence predicates are * evaluated, which will be one of the following values. * */ - public SemanticContext evalPrecedence(Recognizer parser, RuleContext outerContext) { + public SemanticContext evalPrecedence(Recognizer parser, RuleContext parserCallStack) { return this; } @@ -114,8 +114,8 @@ public abstract class SemanticContext { } @Override - public boolean eval(Recognizer parser, RuleContext outerContext) { - RuleContext localctx = isCtxDependent ? outerContext : null; + public boolean eval(Recognizer parser, RuleContext parserCallStack) { + RuleContext localctx = isCtxDependent ? parserCallStack : null; return parser.sempred(localctx, ruleIndex, predIndex); } @@ -157,13 +157,13 @@ public abstract class SemanticContext { } @Override - public boolean eval(Recognizer parser, RuleContext outerContext) { - return parser.precpred(outerContext, precedence); + public boolean eval(Recognizer parser, RuleContext parserCallStack) { + return parser.precpred(parserCallStack, precedence); } @Override - public SemanticContext evalPrecedence(Recognizer parser, RuleContext outerContext) { - if (parser.precpred(outerContext, precedence)) { + public SemanticContext evalPrecedence(Recognizer parser, RuleContext parserCallStack) { + if (parser.precpred(parserCallStack, precedence)) { return SemanticContext.NONE; } else { @@ -269,19 +269,19 @@ public abstract class SemanticContext { * unordered.

*/ @Override - public boolean eval(Recognizer parser, RuleContext outerContext) { + public boolean eval(Recognizer parser, RuleContext parserCallStack) { for (SemanticContext opnd : opnds) { - if ( !opnd.eval(parser, outerContext) ) return false; + if ( !opnd.eval(parser, parserCallStack) ) return false; } return true; } @Override - public SemanticContext evalPrecedence(Recognizer parser, RuleContext outerContext) { + public SemanticContext evalPrecedence(Recognizer parser, RuleContext parserCallStack) { boolean differs = false; List operands = new ArrayList(); for (SemanticContext context : opnds) { - SemanticContext evaluated = context.evalPrecedence(parser, outerContext); + SemanticContext evaluated = context.evalPrecedence(parser, parserCallStack); differs |= (evaluated != context); if (evaluated == null) { // The AND context is false if any element is false @@ -366,19 +366,19 @@ public abstract class SemanticContext { * unordered.

*/ @Override - public boolean eval(Recognizer parser, RuleContext outerContext) { + public boolean eval(Recognizer parser, RuleContext parserCallStack) { for (SemanticContext opnd : opnds) { - if ( opnd.eval(parser, outerContext) ) return true; + if ( opnd.eval(parser, parserCallStack) ) return true; } return false; } @Override - public SemanticContext evalPrecedence(Recognizer parser, RuleContext outerContext) { + public SemanticContext evalPrecedence(Recognizer parser, RuleContext parserCallStack) { boolean differs = false; List operands = new ArrayList(); for (SemanticContext context : opnds) { - SemanticContext evaluated = context.evalPrecedence(parser, outerContext); + SemanticContext evaluated = context.evalPrecedence(parser, parserCallStack); differs |= (evaluated != context); if (evaluated == NONE) { // The OR context is true if any element is true