Tôi đã phát triển một ngữ pháp phức tạp bằng cách sử dụng Antlr 3 sử dụng cây AST. ANTLR tạo ra Lexer và Parser. Vấn đề là khi người dùng nhập một cú pháp không hợp lệ ví dụ, ngữ pháp đang chờ ';'. Người dùng không nhập mã này, sau đó trong IDE Eclipse của tôi, tôi nhận được Ngoại lệ sau:Ngoại lệ xử lý Antlr
line 1:24 mismatched input '<EOF>' expecting ';'
Làm thế nào ngoại lệ này có thể được xử lý vì tôi cố bắt ngoại lệ này, nhưng ngoại lệ không bị bắt. Đây có phải là ngoại lệ không? Tôi dường như không hiểu tại sao ngoại lệ này không bị bắt. Tôi đã cố gắng để tìm hiểu, tuy nhiên trang web Antlr dường như xuống một thời gian ngay bây giờ.
Tôi đã xem như sau: ANTLR exception handling with "$", Java và làm theo ví dụ đó, nhưng khi Lexer tạo mã bằng cách thêm RuntimeException(), tôi nhận được mã không thể truy cập được.
Tôi không biết phải làm gì.
Khi tôi cố gắng để có được số lượng các lỗi cú pháp từ phân tích cú pháp nó sẽ hiển thị 0.
EDIT:
Tôi đã tìm thấy một giải pháp mà hoạt động bằng cách nhìn vào: ANTLR not throwing errors on invalid input
Tuy nhiên, khi Tôi cố gắng để có được thông điệp ngoại lệ trở lại, nó là null. Tôi đã thiết lập mọi thứ chính xác chưa? Xin vui lòng xem mẫu ngữ pháp:
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());
}
}*/
EDIT:
Hãy xem những gì tôi có cho đến nay:
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;
}
}
Vì vậy, khi tôi nhập như sau: SELECT * FROM tên_bảng
không a ';' Tôi nhận được một MismatchedTokenException:
catch(Exception e) {
System.out.println("Exception : " + " " e);
}
Khi tôi cố gắng:
e.getMessage();
nó sẽ trả về null.
Điều này không hoạt động. Khi tôi cố gắng lấy lại tin nhắn, tôi sẽ lấy lại giá trị như bình thường. – user1646481
Vui lòng xem chỉnh sửa ở trên với những gì tôi có ngay bây giờ. Có lẽ tôi đang làm điều gì sai ở đây. Tôi không muốn theo dõi các ngoại lệ nhưng thực sự in chúng. – user1646481
Không chắc chắn nếu điều này giúp: http://stackoverflow.com/questions/4627244/catching-errors-in-antlr-and-finding-parent – user1646481