我使用antlr生成我的解析器,但我想覆盖一些错误报告。目前,如果我提供一些不正确的语法,例如缺少令牌,antlr会给出错误“第1行11行缺少TYPE'。'”
但是我无法找到输出此错误的方法。正如我原先认为的那样,它不是在reportError()方法中。有谁知道消息的生成地点?
谢谢!
答案 0 :(得分:3)
MissingTokenException
通过reportError(...)
。假设你想使用下面的语法解析作业:
grammar T;
parse : assignment EOF;
assignment : Id '=' Number ';';
Number : '0'..'9'+ ('.' '0'..'9'+)?;
Id : ('a'..'z' | 'A'..'Z')+;
Space : ' ' {skip();};
现在只需覆盖reportError(...)
方法,如下所示:
grammar T;
@parser::members {
@Override
public void reportError(RecognitionException e) {
System.out.println("CUSTOM ERROR...\n" + e);
}
}
parse : assignment EOF;
assignment : Id '=' Number ';';
Number : '0'..'9'+ ('.' '0'..'9'+)?;
Id : ('a'..'z' | 'A'..'Z')+;
Space : ' ' {skip();};
然后尝试解析"= 123;"
(缺少Id
):
java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main "= 123;"
CUSTOM ERROR...
MissingTokenException(inserted [@-1,0:0='<missing Id>',<4>,1:0] at =)
如您所见,自定义错误消息正在打印到控制台。
像“没有可行的替代方案......”这样的警告是词法分析器中的一个问题,而不是解析器。当词法分析器遇到你在语法中没有考虑的角色时(或者至少不是一个合适的角色),就会发生这种情况。
假设您解析输入a = 123:
(请注意最后的:
而不是;
)。词法分析器现在会产生“没有可行的替代......”警告,因为我没有为:
定义任何标记。
解决此类错误的一个简单解决方案是在词法分析器语法的末尾添加一个“全能”规则,该规则将匹配之前任何词法规则不匹配的任何字符。每当这种“全能”规则匹配时,你只需在该规则的@after{...}
块中抛出异常(或者做其他事情!)。
这是一个演示:
grammar T;
@parser::members {
@Override
public void reportError(RecognitionException e) {
System.out.println("CUSTOM ERROR...\n" + e);
}
}
parse : assignment EOF;
assignment : Id '=' Number ';';
Number : '0'..'9'+ ('.' '0'..'9'+)?;
Id : ('a'..'z' | 'A'..'Z')+;
Space : ' ' {skip();};
FallThrough
@after{
throw new RuntimeException(String.format(
"Encountered an illegal char on line \%d, column \%d: '\%s'",
getLine(), getCharPositionInLine(), getText()
)
);
}
: . // match any char not matched by Number, Id or Space
;
如果您现在解析a = 123:
,您将在控制台上看到以下内容:
Exception in thread "main" java.lang.RuntimeException:
Encountered an illegal char on line 1, column 8: ':'
...