Report InputMismatchException with original context information
Fixes #1922
This commit is contained in:
parent
c41426c87e
commit
0803c74eb2
|
@ -618,4 +618,28 @@ public class ParserErrorsDescriptors {
|
|||
public String grammar;
|
||||
|
||||
}
|
||||
|
||||
public static class ExtraneousInput extends BaseParserTestDescriptor {
|
||||
public String input = "baa";
|
||||
public String output = null;
|
||||
public String errors = "line 1:0 mismatched input 'b' expecting {<EOF>, 'a'}\n";
|
||||
public String startRule = "file";
|
||||
public String grammarName = "T";
|
||||
|
||||
/**
|
||||
grammar T;
|
||||
|
||||
member : 'a';
|
||||
body : member*;
|
||||
file : body EOF;
|
||||
B : 'b';
|
||||
*/
|
||||
@CommentHasStringValue
|
||||
public String grammar;
|
||||
|
||||
@Override
|
||||
public boolean ignore(String targetName) {
|
||||
return !"Java".equals(targetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -283,11 +283,16 @@ public class SemPredEvalParserDescriptors {
|
|||
public String input = "s\n\n\nx\n";
|
||||
public String output = "(file_ (para (paraContent s) \\n \\n) (para (paraContent \\n x \\n)) <EOF>)\n";
|
||||
/**
|
||||
line 5:0 mismatched input '<EOF>' expecting '
|
||||
'
|
||||
line 5:0 mismatched input '<EOF>' expecting {'s', '
|
||||
', 'x'}
|
||||
*/
|
||||
@CommentHasStringValue
|
||||
public String errors;
|
||||
|
||||
@Override
|
||||
public boolean ignore(String targetName) {
|
||||
return !"Java".equals(targetName);
|
||||
}
|
||||
}
|
||||
|
||||
public static class PredFromAltTestedInLoopBack_2 extends PredFromAltTestedInLoopBack {
|
||||
|
|
|
@ -36,6 +36,21 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
|
|||
|
||||
protected IntervalSet lastErrorStates;
|
||||
|
||||
/**
|
||||
* This field is used to propagate information about the lookahead following
|
||||
* the previous match. Since prediction prefers completing the current rule
|
||||
* to error recovery efforts, error reporting may occur later than the
|
||||
* original point where it was discoverable. The original context is used to
|
||||
* compute the true expected sets as though the reporting occurred as early
|
||||
* as possible.
|
||||
*/
|
||||
protected ParserRuleContext nextTokensContext;
|
||||
|
||||
/**
|
||||
* @see #nextTokensContext
|
||||
*/
|
||||
protected int nextTokensState;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -225,7 +240,20 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
|
|||
|
||||
// try cheaper subset first; might get lucky. seems to shave a wee bit off
|
||||
IntervalSet nextTokens = recognizer.getATN().nextTokens(s);
|
||||
if (nextTokens.contains(Token.EPSILON) || nextTokens.contains(la)) {
|
||||
if (nextTokens.contains(la)) {
|
||||
// We are sure the token matches
|
||||
nextTokensContext = null;
|
||||
nextTokensState = ATNState.INVALID_STATE_NUMBER;
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextTokens.contains(Token.EPSILON)) {
|
||||
if (nextTokensContext == null) {
|
||||
// It's possible the next token won't match; information tracked
|
||||
// by sync is restricted for performance.
|
||||
nextTokensContext = recognizer.getContext();
|
||||
nextTokensState = recognizer.getState();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -450,7 +478,14 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
|
|||
}
|
||||
|
||||
// even that didn't work; must throw the exception
|
||||
throw new InputMismatchException(recognizer);
|
||||
InputMismatchException e;
|
||||
if (nextTokensContext == null) {
|
||||
e = new InputMismatchException(recognizer);
|
||||
} else {
|
||||
e = new InputMismatchException(recognizer, nextTokensState, nextTokensContext);
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,4 +13,10 @@ public class InputMismatchException extends RecognitionException {
|
|||
super(recognizer, recognizer.getInputStream(), recognizer._ctx);
|
||||
this.setOffendingToken(recognizer.getCurrentToken());
|
||||
}
|
||||
|
||||
public InputMismatchException(Parser recognizer, int state, ParserRuleContext ctx) {
|
||||
super(recognizer, recognizer.getInputStream(), ctx);
|
||||
this.setOffendingState(state);
|
||||
this.setOffendingToken(recognizer.getCurrentToken());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue