对于ANTLR3异常,antlrworks可以工作,但生成的java代码无法工作
我想解析包含对于ANTLR3异常,antlrworks可以工作,但生成的java代码无法工作,java,antlr,antlr3,Java,Antlr,Antlr3,我想解析包含和和或关键字的SQL表达式。问题是Antlrwork可以为错误语法抛出异常,但生成的java代码不能抛出异常。同时,我发现生成的java代码是一个错误,只能生成AST的一半,并且没有错误信息,执行路径无法到达异常点 这是我的dot g文件: grammar ContainsExpr; options { language = Java; output=AST; ASTLabelType=CommonTree; } to
和
和或
关键字的SQL表达式。问题是Antlrwork
可以为错误语法抛出异常,但生成的java代码不能抛出异常。同时,我发现生成的java代码是一个错误,只能生成AST的一半,并且没有错误信息,执行路径无法到达异常点
这是我的dot g文件:
grammar ContainsExpr;
options {
language = Java;
output=AST;
ASTLabelType=CommonTree;
}
tokens {
DIVIDE = '/' ;
PLUS = '+' ;
MINUS = '-' ;
STAR = '*' ;
MOD = '%' ;
AMPERSAND = '&' ;
TILDE = '~' ;
BITWISEOR = '|' ;
COMMA = ',';
DOT = '.';
LPAREN = '(' ;
RPAREN = ')' ;
EQUAL = '=';
NOTEQUAL = '!=';
LESSTHANOREQUALTO = '<=';
LESSTHAN = '<';
GREATERTHANOREQUALTO = '>=';
GREATERTHAN = '>';
AND = 'AND';
OR = 'OR' ;
TRUE = 'TRUE';
FALSE = 'FALSE';
KW_NEAR = 'NEAR';
DOUBLE_QUOTE = '\"';
SINGLE_QUOTE = '\'';
TOK_NEAR;
TOK_ITEMS;
TOK_PARAMETER;
TOK_WILDCARDS;
}
@header {
package test1;
}
@members {
//override method
public void reportError(RecognitionException e) {
displayRecognitionError(this.getTokenNames(), e);
}
@Override
public void emitErrorMessage(String message) {
throw new RuntimeException(message);
}
}
@lexer::header {
package test1;
}
@lexer::members {
//override method
public void reportError(RecognitionException e) {
displayRecognitionError(this.getTokenNames(), e);
}
}
@rulecatch {
catch (RecognitionException e) {
reportError(e);
throw e;
}
}
// LITERALS
fragment
Letter
: 'a'..'z' | 'A'..'Z'
;
fragment
Digit
:
'0'..'9'
;
fragment
Exponent
:
('e' | 'E') ( PLUS|MINUS )? (Digit)+
;
Number
:
(Digit)+ ( DOT (Digit)* (Exponent)? | Exponent)?
;
fragment
UnquotedString
:
( ~(SINGLE_QUOTE|DOUBLE_QUOTE|' '|'\t'|'\n'|LPAREN|RPAREN|COMMA))+
;
fragment
QuotedLiteral
:
DOUBLE_QUOTE ( ~(DOUBLE_QUOTE|'\\') | ('\\' .) )* DOUBLE_QUOTE
;
Parameter
:
UnquotedString | QuotedLiteral
;
WS : (' '|'\r'|'\t'|'\n'|'\u000C')* {$channel=HIDDEN;}
;
eval
:
searchCondition
;
//AND has precedence over OR
searchCondition
:
andExpr (precedenceOrOperator^ andExpr)*
;
andExpr
:
subCondition (precedenceAndOperator^ subCondition)*
;
precedenceAndOperator
:
AND | AMPERSAND
;
precedenceOrOperator
:
OR | BITWISEOR
;
subCondition
:
atom
| LPAREN searchCondition RPAREN
;
atom
:
subEressixpon
;
subEressixpon
:
Parameter -> ^(TOK_PARAMETER Parameter)
;
在
while
循环中,当LA1_0
是或关键字时,它将是异常的正常到达点。所以不能抛出异常。我已经有一段时间没有使用antlr了,但您可以在这里查看一下
您可以从解析器获取错误消息
希望这有帮助。干杯好的,我可以先确认一下你的问题,但经过一点尝试后,它成功了
我改变了三件事:
将lexer规则放在解析器规则之后
在顶级解析器规则中添加了EOF符号
仅重写解析器和lexer中所需的两个方法“reportError”
玩得开心,不断地问^^
grammar ContainsExpr;
options {
language = Java;
output=AST;
ASTLabelType=CommonTree;
}
tokens {
DIVIDE = '/' ;
PLUS = '+' ;
MINUS = '-' ;
STAR = '*' ;
MOD = '%' ;
AMPERSAND = '&' ;
TILDE = '~' ;
BITWISEOR = '|' ;
COMMA = ',';
DOT = '.';
LPAREN = '(' ;
RPAREN = ')' ;
EQUAL = '=';
NOTEQUAL = '!=';
LESSTHANOREQUALTO = '<=';
LESSTHAN = '<';
GREATERTHANOREQUALTO = '>=';
GREATERTHAN = '>';
AND = 'AND';
OR = 'OR' ;
TRUE = 'TRUE';
FALSE = 'FALSE';
KW_NEAR = 'NEAR';
DOUBLE_QUOTE = '\"';
SINGLE_QUOTE = '\'';
TOK_NEAR;
TOK_ITEMS;
TOK_PARAMETER;
TOK_WILDCARDS;
}
@header {
package test1;
}
@lexer::header {
package test1;
}
@parser::members {
@Override
public void reportError(RecognitionException e) {
throw new RuntimeException("I quit!\n" + e.getMessage());
}
}
@lexer::members {
@Override
public void reportError(RecognitionException e) {
throw new RuntimeException("I quit!\n" + e.getMessage());
}
}
eval
:
searchCondition EOF
;
//AND has precedence over OR
searchCondition
:
andExpr (precedenceOrOperator^ andExpr)*
;
andExpr
:
subCondition (precedenceAndOperator^ subCondition)*
;
precedenceAndOperator
:
AND | AMPERSAND
;
precedenceOrOperator
:
OR | BITWISEOR
;
subCondition
:
atom
| LPAREN searchCondition RPAREN
;
atom
:
subEressixpon
;
subEressixpon
:
Parameter -> ^(TOK_PARAMETER Parameter)
;
// LITERALS
fragment
Letter
: 'a'..'z' | 'A'..'Z'
;
fragment
Digit
:
'0'..'9'
;
fragment
Exponent
:
('e' | 'E') ( PLUS|MINUS )? (Digit)+
;
Number
:
(Digit)+ ( DOT (Digit)* (Exponent)? | Exponent)?
;
fragment
UnquotedString
:
( ~(SINGLE_QUOTE|DOUBLE_QUOTE|' '|'\t'|'\n'|LPAREN|RPAREN|COMMA))+
;
fragment
QuotedLiteral
:
DOUBLE_QUOTE ( ~(DOUBLE_QUOTE|'\\') | ('\\' .) )* DOUBLE_QUOTE
;
Parameter
:
UnquotedString | QuotedLiteral
;
WS : (' '|'\r'|'\t'|'\n'|'\u000C')* {$channel=HIDDEN;}
;
结果
java.lang.RuntimeException: I quit!
null
更新
我发现自己是我答案的一部分
请张贴完整的语法。这里缺少lexer规则(例如,符号),请将我的答案标记为解决问题的答案(如果是),或者发布更新,说明仍然存在的问题you@Rainer问题是生成的java代码无法获取异常,但是ANLTRWorks和anltr3的eclipse插件在解释器输入错误时都会引发异常。我想你可以在语法中提供一些选项来修改lexer和parser的行为啊,我刚刚想到一件事。若我没记错的话,你们可能想看看EOF标记,并将其添加到顶级解析器规则的末尾。它实际上只是一个很轻的内存,但EOF令牌和异常处理之间有某种关联。嗨,你们应该打印异常的堆栈跟踪。null
不是指针异常。RecognitionException
没有getMessage()方法。这只是一个概念的证明。如果是,请标记为已解决。谢谢,我刚刚从我链接到的另一个答案复制了异常块。您应该将异常包装到新的RuntimeException(“…”,e)中
package test1;
import junit.framework.TestCase;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.TokenStream;
import org.junit.Assert;
public class Test extends TestCase {
public void test() {
String test = "expr1 epxr2"; // AND missing
ANTLRStringStream input = new ANTLRStringStream(test);
TokenStream tokens = new CommonTokenStream(new ContainsExprLexer(input));
ContainsExprParser parser = new ContainsExprParser(tokens);
try {
parser.eval();
Assert.fail("Should throw Exception");
} catch (Exception e) {
//jippi
System.out.println(e);
}
}
}
java.lang.RuntimeException: I quit!
null