1

私は次のようなルールを持っています:

declaration returns [RuntimeObject obj]: 
    DECLARE label value { $obj = new RuntimeObject($label.text, $value.text); };

残念ながら、nullであるRuntimeObjectため、コンストラクターで例外がスローされます。$label.textデバッグ出力などを調べると、「ラベル」との一致が実際には失敗したことがわかりますが、Antlr ランタイムは、より役立つエラー メッセージを表示する目的で「役立つように」一致を続行します ( http://www.antlr.org /blog/antlr3/error.handling.tml )。

わかりました、これがいくつかの状況でどのように役立つかはわかりますが、どうすれば Antlr にそれをやめるように指示できますか? defaultErrorHandler=falsev2 からのオプションはなくなったようです。

4

3 に答える 3

2

私は Antlr についてあまり詳しくないので、これは的外れかもしれませんが、この移行ページの「エラー処理」というタイトルのセクションが役に立ちます。

@rulecatch { }エラー処理を完全に無効にするか、回復を試みない独自の実装でのmismatch()メソッドをオーバーライドすることができます。BaseRecogniser問題の説明から、そのページの例は、まさにあなたが望むことをしているようです。

于 2009-09-08T18:14:30.983 に答える
0

次のように、reportError(RecognitionException) メソッドをオーバーライドして、例外を出力する代わりに再スローすることもできます。

@parser::members {
    @Override
    public void reportError(RecognitionException e) {
        throw new RuntimeException(e);
    }
}

ただし、これ (または ire_and_curses による解決策) が必要かどうかはわかりません。解析試行ごとにエラーが 1 つしか発生しないため、次のエラーを見つけるために修正することができます。回復しようとすると (ANTLR は問題ありません)、1 回の試行で複数のエラーが発生し、それらすべてを修正できます。

于 2009-09-09T08:14:49.667 に答える
0

mismatchおよびメソッドをオーバーライドして、例外がすぐにスローされるようにする必要がありますrecoverFromMismatchedSet(例は Java の場合です)。

@members {
    protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException {
        throw new MismatchedTokenException(ttype, input);
    }

    public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException {
        throw e;
    }
}

次に、パーサーがこれらの例外を処理する方法を変更して、それらが飲み込まれないようにする必要があります。

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

(パーサー内のすべてのルール マッチング メソッドの本体は、tryこれをブロックとして、catchブロックで囲まれます。)


比較のために、recoverFromMismatchedSet継承された fromのデフォルトの実装BaseRecognizer:

public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow)  throws RecognitionException {
    if (mismatchIsMissingToken(input, follow)) {
        reportError(e);
        return getMissingSymbol(input, e, Token.INVALID_TOKEN_TYPE, follow);
    }

    throw e;
}

デフォルトのルールキャッチ:

catch (RecognitionException re) {
    reportError(re);
    recover(input,re);
}
于 2012-05-18T18:16:40.570 に答える