forked from jasder/antlr
Document ANTLRErrorListener and DiagnosticErrorListener (fixes #265)
This commit is contained in:
parent
f1f134c962
commit
780b7ac4ce
|
@ -31,6 +31,8 @@
|
||||||
package org.antlr.v4.runtime;
|
package org.antlr.v4.runtime;
|
||||||
|
|
||||||
import org.antlr.v4.runtime.atn.ATNConfigSet;
|
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.dfa.DFA;
|
||||||
import org.antlr.v4.runtime.misc.NotNull;
|
import org.antlr.v4.runtime.misc.NotNull;
|
||||||
import org.antlr.v4.runtime.misc.Nullable;
|
import org.antlr.v4.runtime.misc.Nullable;
|
||||||
|
@ -80,36 +82,102 @@ public interface ANTLRErrorListener {
|
||||||
String msg,
|
String msg,
|
||||||
@Nullable RecognitionException e);
|
@Nullable RecognitionException e);
|
||||||
|
|
||||||
/** Called when the parser detects a true ambiguity: an input
|
/**
|
||||||
* sequence can be matched literally by two or more pass through
|
* This method is called by the parser when a full-context prediction
|
||||||
* the grammar. ANTLR resolves the ambiguity in favor of the
|
* results in an ambiguity.
|
||||||
* alternative appearing first in the grammar. The start and stop
|
* <p/>
|
||||||
* index are zero-based absolute indices into the token
|
* When {@code exact} is {@code true}, <em>all</em> of the alternatives in
|
||||||
* stream. ambigAlts is a set of alternative numbers that can
|
* {@code ambigAlts} are viable, i.e. this is reporting an exact ambiguity.
|
||||||
* match the input sequence. This method is only called when we
|
* When {@code exact} is {@code false}, <em>at least two</em> of the
|
||||||
* are parsing with full context.
|
* 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,
|
void reportAmbiguity(@NotNull Parser recognizer,
|
||||||
DFA dfa, int startIndex, int stopIndex,
|
@NotNull DFA dfa,
|
||||||
|
int startIndex,
|
||||||
|
int stopIndex,
|
||||||
boolean exact,
|
boolean exact,
|
||||||
@NotNull BitSet ambigAlts,
|
@NotNull BitSet ambigAlts,
|
||||||
@NotNull ATNConfigSet configs);
|
@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,
|
void reportAttemptingFullContext(@NotNull Parser recognizer,
|
||||||
@NotNull DFA dfa,
|
@NotNull DFA dfa,
|
||||||
int startIndex, int stopIndex,
|
int startIndex,
|
||||||
|
int stopIndex,
|
||||||
@Nullable BitSet conflictingAlts,
|
@Nullable BitSet conflictingAlts,
|
||||||
@NotNull ATNConfigSet configs);
|
@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
|
* This method is called by the parser when a full-context prediction has a
|
||||||
* warning; it simply notifies you that your grammar is more
|
* unique result.
|
||||||
* complicated than Strong LL can handle. The parser moved up to
|
* <p/>
|
||||||
* full context parsing for that input sequence.
|
* 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,
|
void reportContextSensitivity(@NotNull Parser recognizer,
|
||||||
@NotNull DFA dfa,
|
@NotNull DFA dfa,
|
||||||
int startIndex, int stopIndex,
|
int startIndex,
|
||||||
|
int stopIndex,
|
||||||
int prediction,
|
int prediction,
|
||||||
@NotNull ATNConfigSet configs);
|
@NotNull ATNConfigSet configs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,15 +39,62 @@ import org.antlr.v4.runtime.misc.Nullable;
|
||||||
|
|
||||||
import java.util.BitSet;
|
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 {
|
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
|
@Override
|
||||||
public void reportAmbiguity(@NotNull Parser recognizer,
|
public void reportAmbiguity(@NotNull Parser recognizer,
|
||||||
DFA dfa, int startIndex, int stopIndex,
|
DFA dfa,
|
||||||
|
int startIndex,
|
||||||
|
int stopIndex,
|
||||||
boolean exact,
|
boolean exact,
|
||||||
@Nullable BitSet ambigAlts,
|
@Nullable BitSet ambigAlts,
|
||||||
@NotNull ATNConfigSet configs)
|
@NotNull ATNConfigSet configs)
|
||||||
{
|
{
|
||||||
if (!exact) {
|
if (exactOnly && !exact) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +109,8 @@ public class DiagnosticErrorListener extends BaseErrorListener {
|
||||||
@Override
|
@Override
|
||||||
public void reportAttemptingFullContext(@NotNull Parser recognizer,
|
public void reportAttemptingFullContext(@NotNull Parser recognizer,
|
||||||
@NotNull DFA dfa,
|
@NotNull DFA dfa,
|
||||||
int startIndex, int stopIndex,
|
int startIndex,
|
||||||
|
int stopIndex,
|
||||||
@Nullable BitSet conflictingAlts,
|
@Nullable BitSet conflictingAlts,
|
||||||
@NotNull ATNConfigSet configs)
|
@NotNull ATNConfigSet configs)
|
||||||
{
|
{
|
||||||
|
@ -76,7 +124,8 @@ public class DiagnosticErrorListener extends BaseErrorListener {
|
||||||
@Override
|
@Override
|
||||||
public void reportContextSensitivity(@NotNull Parser recognizer,
|
public void reportContextSensitivity(@NotNull Parser recognizer,
|
||||||
@NotNull DFA dfa,
|
@NotNull DFA dfa,
|
||||||
int startIndex, int stopIndex,
|
int startIndex,
|
||||||
|
int stopIndex,
|
||||||
int prediction,
|
int prediction,
|
||||||
@NotNull ATNConfigSet configs)
|
@NotNull ATNConfigSet configs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,12 +36,20 @@ import java.util.BitSet;
|
||||||
import java.util.Collection;
|
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
|
* @author Sam Harwell
|
||||||
*/
|
*/
|
||||||
public class ProxyErrorListener implements ANTLRErrorListener {
|
public class ProxyErrorListener implements ANTLRErrorListener {
|
||||||
private final Collection<? extends ANTLRErrorListener> delegates;
|
private final Collection<? extends ANTLRErrorListener> delegates;
|
||||||
|
|
||||||
public ProxyErrorListener(Collection<? extends ANTLRErrorListener> delegates) {
|
public ProxyErrorListener(Collection<? extends ANTLRErrorListener> delegates) {
|
||||||
|
if (delegates == null) {
|
||||||
|
throw new NullPointerException("delegates");
|
||||||
|
}
|
||||||
|
|
||||||
this.delegates = delegates;
|
this.delegates = delegates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue