6

スカラー式とベクトル式を処理する文法を書いています。以下の文法は、スカラー式がベクトルから派生でき、ベクトルがスカラーから派生できるという問題を示すために単純化されています。たとえば、ベクトルは、リテラル[1, 2, 3]またはスカラーとベクトルの積2 * [1, 2, 3]( と同等[2, 4, 6]) である可能性があります。スカラーは、リテラル2またはベクトルへのインデックス[1, 2, 3][1]( と同等2) である可能性があります。

grammar LeftRecursion;

Integer
    : [0-9]+
    ;

WhiteSpace
    : [ \t\r\n]+ -> skip
    ;

input
    : expression EOF;

expression
    : scalar
    | vector
    ;

scalar
    : Integer
    | vector '[' Integer ']'
    ;

vector
    : '[' Integer ',' Integer ',' Integer ']'
    | scalar '*' vector
    ;

ANTLR4 でエラーが表示されます: The following sets of rules are mutually left-recursive [scalar, vector]. scalar参照とその逆であるため、これは理にかなっていますvectorが、同時に決定論的でなければなりません。

相互の (間接的な) 左再帰を避けるために、この文法をどのようにリファクタリングしますか? inplace という用語の 1 つを拡張することもできますが、それは完全な文法で多くの重複を招き、ベクトルとスカラーの代替がさらに多くなります。一次式を持つように文法をリファクタリングすることもできますscalar '*' scalarが、有効なvector代替手段として許可したくありません。他のオプションはありますか?

4

2 に答える 2

4

私の知る限り、それを回避する方法はありませんが、間接再帰ルールを排除するために拡張する必要があります。

expression
    : scalar
    | vector
    ;

scalar
    : '[' Integer ',' Integer ',' Integer ']' '[' Integer ']'
    | scalar '*' vector '[' Integer ']'
    | Integer
    ;

vector
    : '[' Integer ',' Integer ',' Integer ']'
    | scalar '*' vector
    ;
于 2013-12-26T22:42:15.087 に答える