2011-12-28 15 views
14

私は書いているJavaツールでANTLRを使用して論理式を解析していますが、生成されたANTLRレクサーとパーサーに無効な入力文字列を渡すと問題が発生します任意の例外。 RecognitionExceptionをスローするのではなく、生成されたファイルはエラーメッセージをコンソールに出力し、エラーが発生していないかのように返して、空のデータが後で実行されるときにプログラムがクラッシュする原因となります。無効な入力でANTLRがエラーをスローしない

ANTLRWorksバージョン1.4.3を使用してファイルを生成しましたが、コンソールに印刷するのではなく、実際にエラーをスローするオプションがあるようですが、何も見つかりませんでした。 ANTLRを実際にエラーメッセージをスローする方法を知っていますか?私は、ANTLRの古いバージョンを使用することでC#のこの同じ問題が解決されたことを知りました。

EDITは:バートは私が探していたものの方向に私を指摘した後、私はこのページの「エラー処理」セクション私は、より正確に望むものでしコードを持っていた

https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Migrating+from+ANTLR+2+to+ANTLR+3

を見つけました。 ANTLRは、例外をキャッチする方法を変更するには、文法ファイルでこれを言うことができます。

@rulecatch { 
    catch (RecognitionException e) { 
    throw e; 
    } 
} 

この力のANTLRは、それを処理し、回復するのではなく、例外をスローします。このセクションには、可能なすべての例外がスローされるように、不一致関数とリカバリ関数をオーバーライドする方法もあります。

答えて

17

簡単に修正があなたのレクサーのパーサのreportError(...)を無効にし、代わりに正しくない構文/入力から回復しようとしているANTLRをさせるのあなた自身の例外をスローするようになります:エラー報告(上

grammar YourGrammar; 

// options/header/tokens 

@parser::members { 
    @Override 
    public void reportError(RecognitionException e) { 
    throw new RuntimeException("I quit!\n" + e.getMessage()); 
    } 
} 

@lexer::members { 
    @Override 
    public void reportError(RecognitionException e) { 
    throw new RuntimeException("I quit!\n" + e.getMessage()); 
    } 
} 

// lexer & parser rules 

詳細と回復):https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Error+reporting+and+recovery

+0

ああ、すっごくありがとうございました、私はちょうど私がやりたい文法ファイルを編集するための簡単な方法でなければなりませんでしたが、ANTLRはちょうど私がいなかったので、大きいですが知っていました何を探すべきか正確に知っている。 –

+0

@BeaMetitiriようこそ。 –

+0

リンクは廃止されました – gvlasov

1

in this answer

を示唆したようにあなたはしかし、antlr4/ANTLR V4へantlr3からの迅速な移行のために、あなたが目を使用することができ、エラー・リスナーを使用する必要がありますあなたの文法通りである:

@parser::members 
{ 
    private final Logger log = LogManager.getLogger(this.getClass().getName()); 
    public java.util.HashMap<String, Double> memory = new java.util.HashMap<String, Double>(); 

    @Override 
    public void notifyErrorListeners(Token offendingToken, String msg, RecognitionException ex) 
    { 
    throw new RuntimeException(msg); 
    } 
} 

@lexer::members 
{ 
    @Override 
    public void recover(RecognitionException ex) 
    { 
    throw new RuntimeException(ex.getMessage()); 
    } 
} 
関連する問題