0

コンパイル プロジェクトのために、私のグループと私は Antlr で文法を定義しています。現在、次のルールに問題があります。

expr: ...
| lvalue expr3 expr2
|  ID '('exprList')' expr2
|... ;


lvalue: ID lvalue2;

lvalue2: '.' ID lvalue2
    | '[' expr ']' lvalue2
    | ;

ご覧のとおり、左辺値は ID になる可能性があり、LL( ) 以外の文法につながります。そこで私の質問は、余分なものを許可せずに文法を LL( ) にするためにどうすれば文法を変更できるかということです。

前もって感謝します !

4

1 に答える 1

0

実際、ルールをリファクタリングできますが、一方で、そこで使用する左再帰構造ではないため、これが LL(k) ではなくなるという結論は正しくありません。同じトークンで始まる 2 つの選択肢しかありません。それを除外することは、前述のように、その状況を克服する 1 つの方法です。もう 1 つの方法は、単純に先読みを増やすことです。これにより、パーサーは次のトークンを調べて、どの alt を取るかを決定することもできます。

文法オプションで先読み値を設定できます。

options {
  k = 2;
}

または特定のルールで、そのルールの値のみを増やします。

expr options { k = 2; }: ...
| lvalue expr3 expr2
|  ID '('exprList')' expr2
|... ;

注: ANTLR 4 には常に無制限の先読みがあるため、この種の問題はありません。

于 2016-02-18T08:05:46.143 に答える