2017-02-28 26 views
0

如何將語法文件中的自定義錯誤消息拋出到java類(解析和lexing被定義的地方)?在antlr3中從語法到Java拋出錯誤

< ----------解析器語法----------->

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

投票反對,因爲這是一個有效(有趣)的問題已經有2個答案(這表明它足夠清楚要問什麼)。 –

回答

1

您不需要在語法中拋出自定義錯誤。相反,您可以安裝自定義錯誤處理程序並在那裏處理異常。我寫了一個fairly complete error handling(但是,對於ANTLR3 C目標)。它可能會給你一些提示,你可以使用它來構建你自己的錯誤消息。

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()做,或者如果它是更長的代碼,更方便子類org.antlr.runtime.Parser和語法的options部分(注意把superClass = MyParser;那爲了解決詞法錯誤,你必須創建一個org.antlr.runtime.Lexer的子類以及詞法分析器的使用)。