次の形式の 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 を返しています。