これは、次の質問の「フォローアップ」です:括弧で囲まれた階層ルートを解析する方法は? (root
ルールの名前が変更されたことに注意してくださいatom
)。
私のANTLR文法では、キャストのサポートを追加しようとしました:
cast : '(' type ')' atom -> ^(CAST type atom);
ここで、それを値ツリーの一部にする必要があります。キャストはそれ自体がアトミックであり、階層のベースになることができ、任意のバイナリ演算 (因数、合計、比較) で使用できるため、atom
(以前のroot
) ルールに準拠する必要があると考えました。
cast : '(' type ')' atom -> ^(CAST type atom);
atom : cast | IDENTIFIER | SELF | literal | constructor | call | indexer | '('! value ')'!;
hierarchy : atom (SUB^ (IDENTIFIER | call | indexer))*;
factor : hierarchy ((MULT^ | DIV^ | MODULO^) hierarchy)*;
sum : factor ((PLUS^ | MINUS^) factor)*;
comparison : sum (comparison_operator^ sum)*;
value : comparison;
幸いなことに、今回はすべてが LL(*) で十分のようです。ただし、からへの無限再帰を取得type
しtype
ます。
type : name=IDENTIFIER (LESSER (generics+=type (SEPARATOR generics+=type)*) GREATER)? -> ^(TYPE $name ^(GENERICS $generics*));
[ルールアトム] 代替案 1 [キャスト]: PAREN_OPEN IDENTIFIER LESSER IDENTIFIER LESSER IDENTIFIER LESSER IDENTIFIER LESSER IDENTIFIER {LESSER, SEPARATOR} 決定などの入力を照合した後、型から型への再帰オーバーフローにより、次に来るものを予測できません
このケースは、 などを反映してい(x<x<x<x<x[</,]
ます。
ANTLR のエラーは非常に不可解です。この正確なエラーを説明している章を読み直しましたが、まだわかりません。私が理解していないのは、スタンドアロンベースでは、type
ルールが無限再帰の警告をトリガーしなかったということです。
どうすれば修正できますか?そして、ANTLR についての私の理解のために、なぜそれが今トリガーされるのか説明してもらえますか?