在antlr3中从语法上丢下错误



如何将自定义错误消息从语法文件扔到Java类(定义解析和Lexing)?

< -------------------------------------->

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
    ;

< ------------------------------------------------------------>

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 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时,它必须给出错误消息为"期望整数",当我错过;时,必须说"丢失的semicolon"。

这样,我必须产生错误消息(我不想要ANTLR产生的默认错误消息,我需要我自己的错误msgs)。

我该如何实现?我是否必须在语法文件中写入错误消息?或Java代码?

您不需要在语法中丢下自定义错误。相反,您安装了自定义错误处理程序并在其中处理异常。我写了一个相当完整的错误处理(但是,对于Antlr3 C目标)。它可能会给您一些提示,您可以用来构建自己的错误消息。

对于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);
      }
      

您可以像对displayRecognitionError()一样在语法的@members部分中覆盖它们,或者如果较长的代码,则更方便地分类org.antlr.runtime.Parser并将superClass = MyParser;放在Grammar的options部分中(请注意,请注意,以此为Lexer的Lexer错误,您还必须创建一个org.antlr.runtime.Lexer的子类,供Lexer使用)。

最新更新