如何将语法文件中的自定义错误消息抛出到java类(定义了解析和lexing)?
< ---------- Parser Grammar ----------->
parser grammar EParser;
@members {
public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
System.out.println("hdr and msg...."+hdr+">>>>>>"+msg);
throw new RuntimeException(hdr + ":" + msg);
}
}
prog
: stat+
;
stat
: expr SEMI
| ID EQU expr SEMI
;
expr
: multExpr ((PRM) multExpr)*
;
multExpr
: atom (MUL atom)*
;
atom
:INT| OPEN expr CLS
;
< ------------------- Java代码--------------->
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
public class TestE {
public static void main(String[] args) throws Exception {
ELexer lexer = new ELexer(new ANTLRStringStream("a=9+8;"));
EParser parser = new EParser(new CommonTokenStream(lexer));
try
{
parser.prog();
System.out.println("Parsing successfully...");
}
catch (Exception e)
{
System.out.println("Other exception : " + e.toString());
}
}
}
< ------------------ Lexer语法-------------->
lexer grammar ELexer;
tokens
{
ID;
INT;
WS;
EQU;
PRM;
OPEN;
CLS;
SEMI;
MUL;
}
@members {
Stack<String> paraphrase = new Stack<String>();
}
ID :('a'..'z'|'A'..'Z')+ ;
INT : '0'..'9'+ ;
EQU:'=';
PRM:'+'|'-';
OPEN:'(';
SEMI:';';
CLS :')';
MUL:'*';
WS : (' '|'\t'|'\n'|'\r')+ {skip();} ;
此处我的输入为a=9+8
。
当我想念8
时,它必须将错误消息指定为“期望整数”,当我想念;
时,它必须说“缺少分号”。
像这样我必须生成错误消息(我不想要由antlr生成的默认错误消息,我需要自己的错误消息)。
我怎样才能做到这一点?我是否必须在语法文件中写入错误消息?还是java代码?
答案 0 :(得分:1)
您不需要在语法中输入自定义错误。而是安装自定义错误处理程序并在那里处理异常。我写了fairly complete error handling(但是,对于ANTLR3 C目标)。它可能会为您提供一些提示,您可以使用它来构建自己的错误消息。
答案 1 :(得分:0)
对于Java目标,您可能希望覆盖以下一种或多种方法:
org.antlr.runtime.BaseRecognizer.getErrorHeader()
org.antlr.runtime.BaseRecognizer.getErrorMessage()
org.antlr.runtime.BaseRecognizer.emitErrorMessage()
org.antlr.runtime.BaseRecognizer.displayRecognitionError()
将它们粘合在一起:
public void displayRecognitionError(String[] tokenNames,
RecognitionException e)
{
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
emitErrorMessage(hdr+" "+msg);
}
您可以像使用@members
一样在语法的displayRecognitionError()
部分覆盖它们,或者如果它的代码更长,则可以更方便地继承{{1}并将org.antlr.runtime.Parser
放入语法的superClass = MyParser;
部分(请注意,对于词法错误也是这样做的,您必须创建{{1}的子类也适合使用词法分析器。)