我使用AST樹開發了一個使用Antlr 3的複雜語法。 ANTLR生成Lexer和Parser。問題是,當用戶輸入一個無效的語法時,語法期望爲';'。用戶不會在我的Eclipse IDE進入這個,然後我得到以下異常:Antlr處理異常
line 1:24 mismatched input '<EOF>' expecting ';'
這怎麼能例外處理,因爲我試圖抓住這一例外,但例外的是沒有逮住。這是一個例外嗎?我似乎不明白爲什麼這個例外沒有被捕獲。我試圖找出,但Antlr網站似乎已停機一段時間了。
我看了下面的內容:ANTLR exception handling with "$", Java並遵循該示例,但是當Lexer通過添加RuntimeException()生成代碼時,我得到無法訪問的代碼。
我不知道該怎麼做。
當我試圖從它顯示的解析器有語法錯誤的數字0
編輯:
我已經發現,通過在尋找有效的解決方案:ANTLR not throwing errors on invalid input
然而,當,我嘗試獲取異常消息,它是空的。我是否正確設置了一切?請參閱樣本語法:
grammar i;
options {
output=AST;
}
@header {
package com.data;
}
@rulecatch {
catch(RecognitionException e) {
throw e;
}
}
// by having these below it makes no difference
/**@parser::members {
@Override
public void reportError(RecognitionException e) {
throw new RuntimeException("Exception : " + " " + e.getMessage());
}
}
@lexer::members {
@Override
public void reportError(RecognitionException e) {
throw new RuntimeException("Exception : " + " " + e.getMessage());
}
}*/
編輯:
請看看我到目前爲止有:
grammar i;
options {
output=AST;
}
@header {
package com.data;
}
@rulecatch {
// ANTLR does not generate its normal rule try/catch
catch(RecognitionException e) {
throw e;
}
}
@parser::members {
@Override
public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
throw new RuntimeException(hdr + ":" + msg);
}
}
@lexer::members {
@Override
public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
throw new RuntimeException(hdr + ":" + msg);
}
}
operatorLogic : 'AND' | 'OR';
value : STRING;
query : (select)*;
select : 'SELECT'^ functions 'FROM table' filters?';';
operator : '=' | '!=' | '<' | '>' | '<=' | '>=';
filters : 'WHERE'^ conditions;
members : STRING operator value;
conditions : (members (operatorLogic members)*);
functions : '*';
STRING : ('a'..'z'|'A'..'Z')+;
WS : (' '|'\t'|'\f'|'\n'|'\r')+ {skip();}; // handle white space between keywords
public class Processor {
public Processor() {
}
/**
* This method builds the MQL Parser.
* @param args the args.
* @return the built IParser.
*/
private IParser buildMQLParser(String query) {
CharStream cs = new ANTLRStringStream(query);
// the input needs to be lexed
ILexer lexer = new ILexer(cs);
CommonTokenStream tokens = new CommonTokenStream();
IParser parser = new IParser(tokens);
tokens.setTokenSource(lexer);
// use the ASTTreeAdaptor so that the grammar is aware to build tree in AST format
parser.setTreeAdaptor((TreeAdaptor) new ASTTreeAdaptor().getASTTreeAdaptor());
return parser;
}
/**
* This method parses the MQL query.
* @param query the query.
*/
public void parseMQL(String query) {
IParser parser = buildMQLParser(query);
CommonTree commonTree = null;
try {
commonTree = (CommonTree) parser.query().getTree();
}
catch(Exception e) {
System.out.println("Exception :" + " " + e.getMessage());
}
}
}
public class ASTTreeAdaptor {
public ASTTreeAdaptor() {
}
/**
* This method is used to create a TreeAdaptor.
* @return a treeAdaptor.
*/
public Object getASTTreeAdaptor() {
TreeAdaptor treeAdaptor = new CommonTreeAdaptor() {
public Object create(Token payload) {
return new CommonTree(payload);
}
};
return treeAdaptor;
}
}
所以,當我輸入以下內容: SELECT * FROM表
無一個 ';'我得到的一個MismatchedTokenException異常:
catch(Exception e) {
System.out.println("Exception : " + " " e);
}
當我嘗試:
e.getMessage();
返回null。
這也行不通。當我嘗試重新獲取消息時,我照常收到null。 – user1646481
請參閱上面的編輯,我現在有。也許我在這裏做錯了什麼。我不想跟蹤例外,但實際上打印它們。 – user1646481
不知道這是否有助於:http://stackoverflow.com/questions/4627244/catching-errors-in-antlr-and-finding-parent – user1646481