2

次の文法は、この問題を示しています。

// test Antlr4 left recursion associativity
grammar LRA;
@parser::members {
    public static void main(String[] ignored) throws Exception{
        final LRALexer lexer = new LRALexer(new ANTLRInputStream(System.in));
        final LRAParser parser = new LRAParser(new CommonTokenStream(lexer));
        parser.setTrace(true);
        parser.file();
    }
}
ID: [A-Za-z_] ([A-Za-z_]|[0-9])*;
CMA: ',';
SMC: ';';
UNK: . -> skip;
file: punctuated EOF;
punctuated
    : punctuated cma punctuated
    | punctuated smc punctuated
    | expression
    ;
cma: CMA;
smc: SMC;
expression: id;
id: ID;

入力 "a,b,c" を指定すると、リスナー イベント トレース出力を取得します

( 'a' ) ( ',' ( 'b' ) ( ',' ( 'c' ) ) )

ここで、(は、 Enter punctuatedを表し、)はexit punctuatedを表し、他のすべてのルールは、簡潔さと明確さのために省略されています。

調べてみると、このリスナー イベントの順序は右結合解析を表しています。

一般的な慣行と The Definitive Antlr 4 Reference により、次のリスナー イベント トレースに対応する左連想解析が期待されます。

( 'a' ) ( ',' ( 'b' ) ) ( ',' ( 'c' ) )

文法、期待、リスナー イベントの解釈などに何か問題がありますか?

4

1 に答える 1

0

上記の回避策は適切な答えだと思います。生成されたパーサーは優先順位パラメーターを再帰呼び出しに渡す必要があり、優先順位はトークンに関連付けられているため、Antlr がその優先順位を見つけられるように、トークンは再帰ルールで直接使用可能でなければなりません。

作業文法は次のようになります。

// test Antlr4 left recursion associativity
grammar LRA;
@parser::members {
    public static void main(String[] ignored) throws Exception{
        final LRALexer lexer = new LRALexer(new ANTLRInputStream(System.in));
        final LRAParser parser = new LRAParser(new CommonTokenStream(lexer));
        parser.setTrace(true);
        parser.file();
    }
}
ID: [A-Za-z_] ([A-Za-z_]|[0-9])*;
CMA: ',';
SMC: ';';
UNK: . -> skip;
file: punctuated EOF;
punctuated
    : punctuated CMA punctuated
    | punctuated SMC punctuated
    | expression
    ;
expression: id;
id: ID;
于 2013-08-15T16:08:15.003 に答える