私はAntlr 3を使用してASTツリーを使用して複雑な文法を開発しました。 ANTLRはLexerとParserを生成します。問題は、例えば、ユーザーが有効でない構文を入力すると、文法が ';'を予期していることです。ユーザーがこれを入力しない場合、私のEclipse IDEに私は次の例外を取得:私はこの例外をキャッチしようとするためAntlr例外の処理
line 1:24 mismatched input '<EOF>' expecting ';'
どのようにこの例外を処理することができますが、例外がcatchedされていません。これは例外ですか?なぜこの例外がキャッチされていないのか分かりません。私は見つけようとしましたが、Antlrのウェブサイトは今のところダウンしているようです。
ANTLR exception handling with "$", Javaを見て、その例に従いましたが、LexerがRuntimeException()を追加してコードを生成すると、到達不能なコードが取得されます。
私は何をすべきかわかりません。
私は、パーサーから構文エラーの数を取得しようとすると、それは0
EDIT表示されます場合は、しかし、ANTLR not throwing errors on invalid input
:私はを見ることで機能するソリューションを見つけた
を私は、例外メッセージを取得しようとすると、それはnullです。すべてを正しく設定しましたか?
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:
私がこれまで持っているものを見てください:
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なしサンプル文法を参照してください。 a ';'私がしようとすると
catch(Exception e) {
System.out.println("Exception : " + " " e);
}
:私はMismatchedTokenExceptionを取得
e.getMessage();
それはnullを返します。
これも機能しません。メッセージを取り戻そうとすると、いつものようにヌルに戻ります。 – user1646481
私が今持っているもので上記の編集をご覧ください。たぶん私はここで何か間違っています。私は例外を追跡するのではなく、実際にそれらを印刷したいと思います。 – user1646481
これが役立つかどうかわからない場合:http://stackoverflow.com/questions/4627244/catching-errors-in-antlr-and-finding-parent – user1646481