【发布时间】:2011-11-20 23:17:44
【问题描述】:
我正在使用 antlr 生成我的解析器,但我想覆盖一些错误报告。目前,如果我给出一些不正确的语法,例如缺少标记,antlr 会给出错误“line 1:11 missing TYPE at '.'”
但是我找不到这个错误是通过哪种方法输出的。正如我最初认为的那样,它不是在 reportError() 方法中。有谁知道消息是在哪里生成的?
谢谢!
【问题讨论】:
我正在使用 antlr 生成我的解析器,但我想覆盖一些错误报告。目前,如果我给出一些不正确的语法,例如缺少标记,antlr 会给出错误“line 1:11 missing TYPE at '.'”
但是我找不到这个错误是通过哪种方法输出的。正如我最初认为的那样,它不是在 reportError() 方法中。有谁知道消息是在哪里生成的?
谢谢!
【问题讨论】:
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: ':'
...
【讨论】: