尝试覆盖displayRecognitionError
反而:
@parser::members {
...
@Override
public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
throw new RuntimeException(hdr + ":" + msg);
}
...
}
//same code in @lexer::members
如果您想跟踪错误而不是中止,您可以创建一个处理程序接口来跟踪它们:
@parser::members {
...
private YourErrorTrackerInterface errorTracker;
//getter/setter for errorTracker here
@Override
public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
if (errorTracker != null){
errorTracker.addError(e, tokenNames, hdr, msg);
}
}
...
}
//same code in @lexer::members
然后错误跟踪器可以决定是抛出异常还是继续。
上面的代码允许您跟踪“可恢复”错误,ANTLR 可以跳过的错误。仍然有一些场景会产生不可恢复的错误,例如SELECT * FROM table
(没有结局;
)。在这种情况下,您必须捕获异常parseMQL
或者那里附近的某个地方。 (您可以尝试编写自己的恢复代码,但我不建议您这样做。)
这是修改后的parseMQL
显示两种不同类型的解析错误。请注意,我删除了对getMessage
因为并非所有异常都源自RecognitionException
填入。
public void parseMQL(String query) {
iParser parser = buildMQLParser(query);
CommonTree commonTree = null;
try {
commonTree = (CommonTree) parser.query().getTree();
} catch (MismatchedTokenException e){
//not production-quality code, just forming a useful message
String expected = e.expecting == -1 ? "<EOF>" : iParser.tokenNames[e.expecting];
String found = e.getUnexpectedType() == -1 ? "<EOF>" : iParser.tokenNames[e.getUnexpectedType()];
System.out.println("Fatal mismatched token exception: expected " + expected + " but was " + found);
} catch (RecognitionException e) {
System.out.println("Fatal recognition exception " + e.getClass().getName()
+ " : " + e);
} catch (Exception e) {
System.out.println("Other exception : " + e.getMessage());
}
}
Input SELECT * FROM table
产生消息“致命的不匹配令牌异常:预期';'但是”。这个异常是由ANTLR直接产生的。
Input SELECT FROM table;
生成消息“其他异常:第 1:7 行:'FROM table' 处缺少 '*'”。这个异常是由上面的代码产生的。