ANTLRで値を解析しようとしています。これが私の文法の関連部分です:
root : IDENTIFIER | SELF | literal | constructor | call | indexer;
hierarchy : root (SUB^ (IDENTIFIER | call | indexer))*;
factor : hierarchy ((MULT^ | DIV^ | MODULO^) hierarchy)*;
sum : factor ((PLUS^ | MINUS^) factor)*;
comparison : sum (comparison_operator^ sum)*;
value : comparison | '(' value ')';
それらの名前はそれらの役割を非常に説明しているので、各トークンまたはルールについては説明しません。この文法はうまく機能してコンパイルされるのでvalue
、次のようなものを使用して解析できます。
a.b[c(5).d[3] * e()] < e("f")
値の認識に残されているのは、括弧で囲まれた階層ルートを使用できるようにすることだけです。例えば:
(a.b).c
(3 < d()).e
...
素朴に、そして多くの期待なしに、私は私のroot
ルールに次の代替案を追加しようとしました:
root : ... | '(' value ')';
ただし、これはvalue
非LL(*)ismのためにルールに違反します。
rule value has non-LL(*) decision due to recursive rule invocations reachable
from alts 1,2. Resolve by left-factoring or using syntactic predicates or using
backtrack=true option.
決定的なANTLRリファレンスのほとんどを読んだ後でも、私はまだこれらのエラーを理解していません。しかし、私が理解していることは、括弧が開いているのを見ると、ANTLRは括弧で囲まれた値の先頭を見ているか、括弧で囲まれたルートの先頭を見ているかを知ることができないということです。
括弧で囲まれた階層ルートの動作を明確に定義するにはどうすればよいですか?
編集:要求に応じて、追加のルール:
parameter : type IDENTIFIER -> ^(PARAMETER ^(type IDENTIFIER));
constructor : NEW type PAREN_OPEN (arguments+=value (SEPARATOR arguments+=value)*)? PAREN_CLOSE -> ^(CONSTRUCTOR type ^(ARGUMENTS $arguments*)?);
call : IDENTIFIER PAREN_OPEN (values+=value (SEPARATOR values+=value)*)? PAREN_CLOSE -> ^(CALL IDENTIFIER ^(ARGUMENTS $values*)?);
indexer : IDENTIFIER INDEX_START (values+=value (SEPARATOR values+=value)*)? INDEX_END -> ^(INDEXER IDENTIFIER ^(ARGUMENTS $values*));