1つのパス(ファイル全体)で解析するときにうまくいく文法があります。ANTLR4 parsing subrules
ここで、解析をコンポーネントに分割したいと考えています。そして、パーサーをサブルールで実行します。私は、私は、次のルールに表示されますサブルールを解析する他の人を想定して問題に遭遇した:上記のルールは、すべてが正常に動作するためにEOF解析し、トップレベルの開始規則から解析され
thing : LABEL? THING THINGDATA thingClause?
//{System.out.println("G4 Lexer/parser thing encountered");}
;
...
thingClause : ',' ID (',' ID)?
;
。 (EOFには解析されない)サブ規則として解析されると、 "、"文字またはEOF文字のいずれかを見ることを期待しているので、節がなければパーザは動揺する。
ライン8:0ミスマッチ入力「%」期待{「」}
IはEOFを解析する際にトップレベルルールが探しているため、%は正しく、別の 『事』コンポーネントに解析されます。
toprule : thing+
| endOfThingsTokens
;
endOfThingsTokensはEOFの前に発生します。このため、トップレベルのルールが機能する理由が考えられます。
サブルールを解析するには、ANTLR4パーサーが%トークンを受け入れたり無視したりして、 "OK we have thingClauseが表示されていません"と言い、トークンストリームをリセットして次のオブジェクトを別のオブジェクトパーサのインスタンス
この特定のケースでは、私は現在レクサー文法でスキップしているパーサーに改行を渡すためにレクサーを変更できます。これは、現在不要なトークンストリーム内の改行を受け入れるために、他にもたくさんの変更が必要になります。
本質的に、ルールに「レコードの終わり」トークンを持たせるためには何らかの方法が必要です。しかし、私は意味論的述語規則でこれを解決する方法があるのか疑問に思っていました。
何かのように:
thing : { if comma before %}? LABEL? THING THINGDATA thingClause?
| LABEL? THING THINGDATA
;
...
thingClause : ',' ID (',' ID)?
;
上記述語の擬似コードは、オプションthingClauseを隠すでしょうか?特定の「終わり」のトークン(つまり改行)を探すことなく、パーサが1つの「もの」を解析した後にパーサが停止するようには満足できない場合。
私がこれを解決すれば、私は答えを投稿します。
ありがとうございました。私は、EOFを事前注入するための一般的な方法を作成する方法について考えてきました。私はTokenReWriterを見てきましたが、それは私が見てきた例が元のトークンストリームを解析した後に呼び出されるので、それをどのように使いたいのかは分かりません。しかし、私が望むかもしれない場所でEOFトークンを注入するカスタムトークンストリームを作成するのに十分なロープがあるようです。 –
申し訳ありませんが、あなたを奨励するつもりはありませんでした。理論的には可能ですが、それはひどく非実用的なアプローチです。はるかに優れた選択肢は、簡単で標準的なAntlr実装を使用できないように問題を特定して解決することです。 – GRosenberg
@RossYoungbloodもちろん、このサブルールとマッチしたい場合は、最後にEOF( 'thing'ルールを呼び出します)を持つ' thingStandalone'ルールを作成することができます。 –