Document ANTLRErrorListener and DiagnosticErrorListener (fixes #265)

This commit is contained in:
Sam Harwell 2013-06-01 21:54:24 -05:00
parent f1f134c962
commit 780b7ac4ce
3 changed files with 154 additions and 29 deletions

View File

@ -31,6 +31,8 @@
package org.antlr.v4.runtime;
import org.antlr.v4.runtime.atn.ATNConfigSet;
import org.antlr.v4.runtime.atn.ParserATNSimulator;
import org.antlr.v4.runtime.atn.PredictionMode;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.misc.Nullable;
@ -80,36 +82,102 @@ public interface ANTLRErrorListener {
String msg,
@Nullable RecognitionException e);
/** Called when the parser detects a true ambiguity: an input
* sequence can be matched literally by two or more pass through
* the grammar. ANTLR resolves the ambiguity in favor of the
* alternative appearing first in the grammar. The start and stop
* index are zero-based absolute indices into the token
* stream. ambigAlts is a set of alternative numbers that can
* match the input sequence. This method is only called when we
* are parsing with full context.
/**
* This method is called by the parser when a full-context prediction
* results in an ambiguity.
* <p/>
* When {@code exact} is {@code true}, <em>all</em> of the alternatives in
* {@code ambigAlts} are viable, i.e. this is reporting an exact ambiguity.
* When {@code exact} is {@code false}, <em>at least two</em> of the
* alternatives in {@code ambigAlts} are viable for the current input, but
* the prediction algorithm terminated as soon as it determined that at
* least the <em>minimum</em> alternative in {@code ambigAlts} is viable.
* <p/>
* When the {@link PredictionMode#LL_EXACT_AMBIG_DETECTION} prediction mode
* is used, the parser is required to identify exact ambiguities so
* {@code exact} will always be {@code true}.
* <p/>
* This method is not used by lexers.
*
* @param recognizer the parser instance
* @param dfa the DFA for the current decision
* @param startIndex the input index where the decision started
* @param stopIndex the input input where the ambiguity is reported
* @param exact {@code true} if the ambiguity is exactly known, otherwise
* {@code false}. This is always {@code true} when
* {@link PredictionMode#LL_EXACT_AMBIG_DETECTION} is used.
* @param ambigAlts the potentially ambiguous alternatives
* @param configs the ATN configuration set where the ambiguity was
* determined
*/
void reportAmbiguity(@NotNull Parser recognizer,
DFA dfa, int startIndex, int stopIndex,
@NotNull DFA dfa,
int startIndex,
int stopIndex,
boolean exact,
@NotNull BitSet ambigAlts,
@NotNull ATNConfigSet configs);
/**
* This method is called when an SLL conflict occurs and the parser is about
* to use the full context information to make an LL decision.
* <p/>
* If one or more configurations in {@code configs} contains a semantic
* predicate, the predicates are evaluated before this method is called. The
* subset of alternatives which are still viable after predicates are
* evaluated is reported in {@code conflictingAlts}.
* <p/>
* This method is not used by lexers.
*
* @param recognizer the parser instance
* @param dfa the DFA for the current decision
* @param startIndex the input index where the decision started
* @param stopIndex the input index where the SLL conflict occurred
* @param conflictingAlts The specific conflicting alternatives. If this is
* {@code null}, the conflicting alternatives are all alternatives
* represented in {@code configs}.
* @param configs the ATN configuration set where the SLL conflict was
* detected
*/
void reportAttemptingFullContext(@NotNull Parser recognizer,
@NotNull DFA dfa,
int startIndex, int stopIndex,
int startIndex,
int stopIndex,
@Nullable BitSet conflictingAlts,
@NotNull ATNConfigSet configs);
/** Called by the parser when it find a conflict that is resolved
* by retrying the parse with full context. This is not a
* warning; it simply notifies you that your grammar is more
* complicated than Strong LL can handle. The parser moved up to
* full context parsing for that input sequence.
/**
* This method is called by the parser when a full-context prediction has a
* unique result.
* <p/>
* For prediction implementations that only evaluate full-context
* predictions when an SLL conflict is found (including the default
* {@link ParserATNSimulator} implementation), this method reports cases
* where SLL conflicts were resolved to unique full-context predictions,
* i.e. the decision was context-sensitive. This report does not necessarily
* indicate a problem, and it may appear even in completely unambiguous
* grammars.
* <p/>
* {@code configs} may have more than one represented alternative if the
* full-context prediction algorithm does not evaluate predicates before
* beginning the full-context prediction. In all cases, the final prediction
* is passed as the {@code prediction} argument.
* <p/>
* This method is not used by lexers.
*
* @param recognizer the parser instance
* @param dfa the DFA for the current decision
* @param startIndex the input index where the decision started
* @param stopIndex the input index where the context sensitivity was
* finally determined
* @param prediction the unambiguous result of the full-context prediction
* @param configs the ATN configuration set where the unambiguous prediction
* was determined
*/
void reportContextSensitivity(@NotNull Parser recognizer,
@NotNull DFA dfa,
int startIndex, int stopIndex,
int startIndex,
int stopIndex,
int prediction,
@NotNull ATNConfigSet configs);
}

View File

@ -39,15 +39,62 @@ import org.antlr.v4.runtime.misc.Nullable;
import java.util.BitSet;
/**
* This implementation of {@link ANTLRErrorListener} can be used to identify
* certain potential correctness and performance problems in grammars. "Reports"
* are made by calling {@link Parser#notifyErrorListeners} with the appropriate
* message.
*
* <ul>
* <li><b>Ambiguities</b>: These are cases where more than one path through the
* grammar can match the input.</li>
* <li><b>Weak context sensitivity</b>: These are cases where full-context
* prediction resolved an SLL conflict to a unique alternative which equaled the
* minimum alternative of the SLL conflict.</li>
* <li><b>Strong (forced) context sensitivity</b>: These are cases where the
* full-context prediction resolved an SLL conflict to a unique alternative,
* <em>and</em> the minimum alternative of the SLL conflict was found to not be
* a truly viable alternative. Two-stage parsing cannot be used for inputs where
* this situation occurs.</li>
* </ul>
*
* @author Sam Harwell
*/
public class DiagnosticErrorListener extends BaseErrorListener {
/**
* When {@code true}, only exactly known ambiguities are reported.
*/
protected final boolean exactOnly;
/**
* Initializes a new instance of {@link DiagnosticErrorListener} which only
* reports exact ambiguities.
*/
public DiagnosticErrorListener() {
this(true);
}
/**
* Initializes a new instance of {@link DiagnosticErrorListener}, specifying
* whether all ambiguities or only exact ambiguities are reported.
*
* @param exactOnly {@code true} to report only exact ambiguities, otherwise
* {@code false} to report all ambiguities.
*/
public DiagnosticErrorListener(boolean exactOnly) {
this.exactOnly = exactOnly;
}
@Override
public void reportAmbiguity(@NotNull Parser recognizer,
DFA dfa, int startIndex, int stopIndex,
DFA dfa,
int startIndex,
int stopIndex,
boolean exact,
@Nullable BitSet ambigAlts,
@NotNull ATNConfigSet configs)
{
if (!exact) {
if (exactOnly && !exact) {
return;
}
@ -62,7 +109,8 @@ public class DiagnosticErrorListener extends BaseErrorListener {
@Override
public void reportAttemptingFullContext(@NotNull Parser recognizer,
@NotNull DFA dfa,
int startIndex, int stopIndex,
int startIndex,
int stopIndex,
@Nullable BitSet conflictingAlts,
@NotNull ATNConfigSet configs)
{
@ -76,7 +124,8 @@ public class DiagnosticErrorListener extends BaseErrorListener {
@Override
public void reportContextSensitivity(@NotNull Parser recognizer,
@NotNull DFA dfa,
int startIndex, int stopIndex,
int startIndex,
int stopIndex,
int prediction,
@NotNull ATNConfigSet configs)
{

View File

@ -36,12 +36,20 @@ import java.util.BitSet;
import java.util.Collection;
/**
* This implementation of {@link ANTLRErrorListener} dispatches all calls to a
* collection of delegate listeners. This reduces the effort required to support multiple
* listeners.
*
* @author Sam Harwell
*/
public class ProxyErrorListener implements ANTLRErrorListener {
private final Collection<? extends ANTLRErrorListener> delegates;
public ProxyErrorListener(Collection<? extends ANTLRErrorListener> delegates) {
if (delegates == null) {
throw new NullPointerException("delegates");
}
this.delegates = delegates;
}