ANTLR v3 NoViableAltException未显示
考虑以下我的语法摘录:ANTLR v3 NoViableAltException未显示,exception,antlr,Exception,Antlr,考虑以下我的语法摘录: definition : '(' 'define' ( '(' variable def_formals ')' body ')' | variable expression ')' ) ; def_formals : variable* ('.' variable)? ; body : ((d
definition
: '(' 'define'
( '(' variable def_formals ')' body ')'
| variable expression ')'
)
;
def_formals
: variable* ('.' variable)?
;
body
: ((definition)=> definition)* expression+
;
变量是标识符,表达式是scheme的一些表达式(如文本或lambda表达式)。完整的语法可以在我的其他一些问题中找到
所以我测试了整个过程,提出了一个关于NoViableException的问题
到目前为止,一切正常运行的东西都正常运行。
比如说
(define x 5)
(define x 5))
(define x)
是公认的
现在我正在测试解析器不应该识别的内容
比如说
(define x 5)
(define x 5))
(define x)
在行尾报告额外的“)”
但是当我把东西漏掉的时候,比如说
(define x 5)
(define x 5))
(define x)
或
解析器一点也不抱怨。当我检查解释器时,NoviableException正确显示。但是我不知道如何在外部程序(比如java测试类)中显示这个错误
我试图让解析器在他看到的第一个语法错误上崩溃,就像Terrence Parr的书(第252页)中描述的那样,但这也没有帮助。
我也试过类似的东西
private List<String> errors = new LinkedList<String>();
public void displayRecognitionError(String[] tokenNames,
RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
errors.add(hdr + " " + msg);
}
public List<String> getErrors() {
return errors;
}
(我必须替换“有很多方法可以改进错误报告。快速修复方法是重写解析器类中的
emitterrormessage(String message)
,并简单地抛出一个包含所提供消息的异常:
语法T;
@成员{
@凌驾
public void emitErrorMessage(字符串消息){
抛出新的运行时异常(消息);
}
}
定义
:'('define'('variable def形式')'body')'
|变量表达式“')”
)
;
定义形式
:变量*('.'变量)?
;
身体
:((定义)=>定义)*表达式+
;
表达
:INT
;
变量
:ID
;
ID:'a'..'z'+;
INT:'0'…'9';
空格:'{skip();};
您可以使用类对其进行测试:
import org.antlr.runtime.*;
公共班机{
公共静态void main(字符串[]args){
字符串[]测试={
“(定义x5)”,
“(定义x 5))”,
“(定义x)”,
(定义)
};
for(字符串输入:测试){
TLexer lexer=新的TLexer(新的AntlStringStream(输入));
TParser parser=newtparser(newcommontokenstream(lexer));
System.out.println(“\n参数:“+输入”);
试一试{
parser.definition();
}捕获(例外e){
System.out.println(“异常->”+e.getMessage());
}
}
}
}
运行上述类后,您将看到以下内容:
bart@hades:~/Programming/ANTLR/Demos/T$java-cp ANTLR-3.3.jar org.ANTLR.Tool T.g
bart@hades:~/Programming/ANTLR/Demos/T$javac-cp ANTLR-3.3.jar*.java
bart@hades:~/Programming/ANTLR/Demos/T$java-cp.:ANTLR-3.3.jar Main
解析:(定义x5)
解析:(定义x5))
解析:(定义x)
异常->第1:9行“')处缺少整数
解析:(定义)
异常->第1:7行输入“')处无可行的备选方案
如您所见,输入(define x 5))
不会产生异常!这是因为lexer没有问题(它们都是有效的标记),解析器只需接受定义规则:
定义
:'('define'('variable def形式')'body')'
|变量表达式“')”
)
;
如果您希望由于悬空的”)“
”而出现错误,那么您需要在规则末尾添加EOF
标记:
定义
:'('define'('variable def形式')'body')'
|变量表达式“')”
)
EOF
;
我用你的例子重现了这一点,但当我试图将其分配给我的语法时,同样没有发生任何事情。我发布了整个语法,正如上面所示。我试图追踪它,并在他输入规则和离开规则时添加了一些打印输出。我得到的结果是:他输入了规则,但他没有离开它。有什么可能吗在我的语法中,(define x)没有错,因为他认为这是一个宏(rule macro_use),甚至(define)符合规则。无论如何,谢谢!@Sebastian,我没有时间研究你的整个语法。但是你的问题解决了,我在你最后的评论中看到了?正确,但是你的回答很有帮助,因为现在我对antlr中的错误报告机制有了更好的理解。