2016-09-16 4 views
2

Antlrで新しい言語を開発しようとしています。Antlr4認識できないトークンと指定されたセンテンスを検出する方法が無効です

grammar test; 

program : vr'.' to'.' e 
     ; 
e: be 
| be'.' top'.' be 
; 
be: 'fg' 
    | 'fs' 
    | 'mc' 
    ; 
to: 'n' 
    | 'a' 
    | 'ev' 
    ; 
vr: 'er' 
    | 'fp' 
    ; 
top: 'b' 
    | 'af' 
    ; 
Whitespace : [ \t\r\n]+ ->skip 
      ; 

Main.java

String expression = "fp.n.fss"; 
//String expression = "fp.n.fs.fs"; 
ANTLRInputStream input = new ANTLRInputStream(expression); 
testLexer lexer = new testLexer(input); 
CommonTokenStream tokens = new CommonTokenStream(lexer); 
testParser parser = new testParser(tokens); 
//remove listener and add listener does not work 
ParseTree parseTree = parser.program(); 

すべてが有効な文章のために良いです:ここに私の文法ファイルです。しかし、私は意味のあるメッセージを返すために、認識されないトークンと無効な文章を捕捉したい。私の問題の2つのテストケースがあります。

fp.n.fss => anltr gives this error token recognition error at: 's' but i could not handle this error. There are same example error handler class which use BaseErrorListener but in my case it does not work.
fp.n.fs.fs => this sentence is invalid for my grammar but i could not catch. How can i catch invalidations like this sentence?

答えて

2

最初にSOとANTLRセクションにようこそ!エラー処理はよく質問されているトピックの1つと思われますが、Java/ANTLR4のエラー処理については本当に良いスレッドです。

defaultErrorStrategyの機能を拡張して、特定の問題を処理し、別の方法で処理すると、エラー行1:12のトークン認識エラーが 's'に表示されるだけでした。

は、デフォルトのエラー戦略クラスの独自のバージョンを実装することができ、これを行うには:

Parser parser = new testParser(tokens); 
      parser.setErrorHandler(new DefaultErrorStrategy() 
    { 

     @Override 
     public void recover(Parser recognizer, RecognitionException e) { 
      for (ParserRuleContext context = recognizer.getContext(); context != null; context = context.getParent()) { 
       context.exception = e; 
      } 

      throw new ParseCancellationException(e); 
     } 


     @Override 
     public Token recoverInline(Parser recognizer) 
      throws RecognitionException 
     { 
      InputMismatchException e = new InputMismatchException(recognizer); 
      for (ParserRuleContext context = recognizer.getContext(); context != null; context = context.getParent()) { 
       context.exception = e; 
      } 

      throw new ParseCancellationException(e); 
     } 
    }); 

parser.program(); //back to first rule in your grammar 
私もそうでない場合は、読みやすくするためだけでなく、多くのツールので、あなたのパーサと字句解析がアップ文法分割お勧めしたいと思い

.g4ファイル(特にANTLRWORKS 2)を分析するために使用されると、暗黙の宣言について不平を言います。

それは次のような構成に変更することができます例えば:あなたはまた、defaultErrorStrategyクラスhereために利用可能なすべての方法を見つけて、あなたの「新しい」エラー戦略の実装ハンドルにこれらのメソッドを追加することによってでき

grammar test; 

program : vr DOT to DOT e 
     ; 
e: be 
| be DOT top DOT be 
; 
be: FG 
    | FS 
    | MC 
    ; 
to: N 
    | A 
    | EV 
    ; 
vr: ER 
    | FP 
    ; 
top: B 
    | AF 
    ; 
Whitespace : [ \t\r\n]+ ->skip 
      ; 

DOT : '.' 
    ; 

A: 'A'|'a' 
; 

AF: 'AF'|'af' 
; 
N: 'N'|'n' 
; 
MC: 'MC'|'mc' 
; 
EV:'EV'|'ev' 
; 
FS: 'FS'|'fs' 
; 
FP: 'FP'|'fp' 
; 
FG: 'FG'|'fg' 
; 
ER: 'ER'|'er' 
; 
B: 'B'|'b' 
; 

あなたが必要とする例外はありません。

これがうまくいけば、あなたのプロジェクトに幸運がありますように!

+0

まずはお手伝いいただきありがとうございます。しかし、私があなたの不具合の解決策を追加しても、「s」にエラートークンの認識エラーがあります。私の場合は、reportInputMismatchメソッドとreportMissingTokenメソッドが機能しません。このエラーを取り除き、意味のあるエラーメッセージを表示するための手順はありますか? – Yunus

+1

@yunskレクサーに戦略を追加したり、エラーを報告したりすることもできます!このエラー戦略は、「認識されないトークン」エラーを処理します。あるいは、あなたはレクサー定義の最後に "Error Token"を追加することができます:ErrorCharacter:。 ;その結果、認識されていないトークンはすべてトークンに捕らえられ、パーサーに送信され、パーサ内のエラー戦略がトリガーされます。 – FDeitelhoff

+0

@FDeitelhoffテストケース:fp.n.fs.fs結果は 未満では、プログラムを入力し、LT(1)= FP は[0,0 @:12 = 'FP'、<4>、1:0]が消費する消費 ルールプログラム[@ 1,13:13 = '。'、<6>、1:13]ルールプログラム 消費[@ 2,14:18 = 'n'、<5>、1:14]ルールプログラム 消費[@ 3,19:ルールプログラム [@ 4,20:27 = 'fs'、<1>、1:20]ルールプログラム 終了プログラム、LT(1)=。 文法に問題はありますか?パーサーが入力を受け付けるようですが、この文は自分の言語では無効です – Yunus

関連する問題