diff --git a/runtime/Java/src/org/antlr/v4/runtime/DiagnosticErrorListener.java b/runtime/Java/src/org/antlr/v4/runtime/DiagnosticErrorListener.java index d22c269c2..f6188c409 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/DiagnosticErrorListener.java +++ b/runtime/Java/src/org/antlr/v4/runtime/DiagnosticErrorListener.java @@ -30,6 +30,7 @@ package org.antlr.v4.runtime; +import org.antlr.v4.runtime.atn.ATNConfig; import org.antlr.v4.runtime.atn.ATNConfigSet; import org.antlr.v4.runtime.dfa.DFA; import org.antlr.v4.runtime.misc.Interval; @@ -51,7 +52,7 @@ public class DiagnosticErrorListener extends BaseErrorListener { } recognizer.notifyErrorListeners("reportAmbiguity d=" + dfa.decision + - ": ambigAlts=" + ambigAlts + ", input='" + + ": ambigAlts=" + getConflictingAlts(ambigAlts, configs) + ", input='" + recognizer.getTokenStream().getText(Interval.of(startIndex, stopIndex)) + "'"); } @@ -78,4 +79,29 @@ public class DiagnosticErrorListener extends BaseErrorListener { dfa.decision + ", input='" + recognizer.getTokenStream().getText(Interval.of(startIndex, stopIndex)) + "'"); } + + /** + * Computes the set of conflicting or ambiguous alternatives from a + * configuration set, if that information was not already provided by the + * parser. + * + * @param reportedAlts The set of conflicting or ambiguous alternatives, as + * reported by the parser. + * @param configs The conflicting or ambiguous configuration set. + * @return Returns {@code reportedAlts} if it is not {@code null}, otherwise + * returns the set of alternatives represented in {@code configs}. + */ + @NotNull + protected BitSet getConflictingAlts(@Nullable BitSet reportedAlts, @NotNull ATNConfigSet configs) { + if (reportedAlts != null) { + return reportedAlts; + } + + BitSet result = new BitSet(); + for (ATNConfig config : configs) { + result.set(config.alt); + } + + return result; + } } diff --git a/tool/test/org/antlr/v4/test/TestPerformance.java b/tool/test/org/antlr/v4/test/TestPerformance.java index 923ce3737..8cb4d74e4 100644 --- a/tool/test/org/antlr/v4/test/TestPerformance.java +++ b/tool/test/org/antlr/v4/test/TestPerformance.java @@ -1582,15 +1582,6 @@ public class TestPerformance extends BaseTest { } - private static BitSet getRepresentedAlts(ATNConfigSet configs) { - BitSet alts = new BitSet(); - for (ATNConfig config : configs) { - alts.set(config.alt); - } - - return alts; - } - private static class SummarizingDiagnosticErrorListener extends DiagnosticErrorListener { private BitSet _sllConflict; private ATNConfigSet _sllConfigs; @@ -1598,9 +1589,9 @@ public class TestPerformance extends BaseTest { @Override public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact, BitSet ambigAlts, ATNConfigSet configs) { if (COMPUTE_TRANSITION_STATS && DETAILED_DFA_STATE_STATS) { - BitSet sllPredictions = _sllConflict != null ? _sllConflict : getRepresentedAlts(_sllConfigs); + BitSet sllPredictions = getConflictingAlts(_sllConflict, _sllConfigs); int sllPrediction = sllPredictions.nextSetBit(0); - BitSet llPredictions = ambigAlts != null ? ambigAlts : getRepresentedAlts(configs); + BitSet llPredictions = getConflictingAlts(ambigAlts, configs); int llPrediction = llPredictions.cardinality() == 0 ? ATN.INVALID_ALT_NUMBER : llPredictions.nextSetBit(0); if (sllPrediction != llPrediction) { ((StatisticsParserATNSimulator)recognizer.getInterpreter()).nonSll[dfa.decision]++; @@ -1632,14 +1623,14 @@ public class TestPerformance extends BaseTest { int decision = dfa.decision; String rule = recognizer.getRuleNames()[dfa.atnStartState.ruleIndex]; String input = recognizer.getTokenStream().getText(Interval.of(startIndex, stopIndex)); - BitSet representedAlts = getRepresentedAlts(configs); + BitSet representedAlts = getConflictingAlts(conflictingAlts, configs); recognizer.notifyErrorListeners(String.format(format, decision, rule, input, representedAlts)); } @Override public void reportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, ATNConfigSet configs) { if (COMPUTE_TRANSITION_STATS && DETAILED_DFA_STATE_STATS) { - BitSet sllPredictions = _sllConflict != null ? _sllConflict : getRepresentedAlts(_sllConfigs); + BitSet sllPredictions = getConflictingAlts(_sllConflict, _sllConfigs); int sllPrediction = sllPredictions.nextSetBit(0); if (sllPrediction != prediction) { ((StatisticsParserATNSimulator)recognizer.getInterpreter()).nonSll[dfa.decision]++; @@ -1651,12 +1642,11 @@ public class TestPerformance extends BaseTest { } // show the rule name and viable configs along with the base info - String format = "reportContextSensitivity d=%d (%s), input='%s', viable=%s"; + String format = "reportContextSensitivity d=%d (%s), input='%s', viable={%d}"; int decision = dfa.decision; String rule = recognizer.getRuleNames()[dfa.atnStartState.ruleIndex]; String input = recognizer.getTokenStream().getText(Interval.of(startIndex, stopIndex)); - BitSet representedAlts = getRepresentedAlts(configs); - recognizer.notifyErrorListeners(String.format(format, decision, rule, input, representedAlts)); + recognizer.notifyErrorListeners(String.format(format, decision, rule, input, prediction)); } }