0

次の形式の ANTLR Grammar があります。

A - B: more,things

ただし、次のように A または B のいずれかが欠落している場合があります。

  - B: more, things           //Skip
A -  : some, other, things    //Skip
C - D: yet, more, things      //Read this one and following
E - F: things

ANTLR がそれらの行 ( - のどちらかの側が欠落している行) をスキップして、残りの処理を続行するようにします。

基本的に、そのようなもの

  - B: more, things {if (!hasBothParts()) { continueAtNextLine();} };

本から、適切なパーサー ブロックの後に @rulecatch とこのキャッチを提供しました。

catch[RecognitionException re]{
  reportError(re);
  consumeUntil(input, NEWLINE);
  input.consume();
}

EDIT 2 - 代わりにこれをやってみました:

while (input.LA(1) != 6){
  input.consume();
}

これは期待どおりに機能しました。6 は、私にとって「NEWLINE」のトークン識別子です。input.LA(1) != "\n" などの比較を行う方法がわかりません。このようにするのは正しくないことはわかっています。ただ実験しているだけです。正しい方法をご存知でしたら教えてください!:)

ただし、最初のループとは異なり、これは機能します。私は、consumeUntil がチャネル Hidden で NEWLINE を表示していない可能性があると考えています。

NullPointer は、EOF への入力の早送りが原因であると思われるため、input.LT(1) を実行しているときにツリー文法が Null にヒットしています。


ただし、そうすると、ツリー文法で NullPointerException が発生します。

Exception in thread "main" java.lang.NullPointerException
at org.antlr.runtime.tree.BaseTreeAdaptor.isNil(BaseTreeAdaptor.java:70)
at org.antlr.runtime.tree.CommonTreeNodeStream.nextElement(CommonTreeNodeStream.java:93)
at org.antlr.runtime.misc.LookaheadStream.fill(LookaheadStream.java:94)
at org.antlr.runtime.misc.LookaheadStream.sync(LookaheadStream.java:88)
at org.antlr.runtime.misc.LookaheadStream.LT(LookaheadStream.java:119)
....

私が望む動作は、パーサーがコンポーネントが欠落している行をスキップして、残りの行に進むことです。ツリー パーサーは問題にならないはずです。

ANTLR の本は、この問題に関して何も言及していません。

また、 ANTLR Error Recoveryはこれらの線に沿って何かを言及していると思いますが、提供されたソリューションはかなり複雑/醜く、2004 年にさかのぼります。

ありがとうございました。

編集これが役立つ場合、生成されたツリー文法の次の行が原因でエラーが発生しました。

retval.start = input.LT(1);

これは、何も呼び出されていないと思います。つまり、LT(1) はスキップしたため、Null を返しています。

4

0 に答える 0