Antlr4左递归规则似乎产生了右关联解析



以下语法说明了这个问题:

// 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' ) ) )

其中表示输入加标点的代表退出加标点的,为了简洁明了,省略了所有其他规则。

通过检查,侦听器事件的这种顺序表示正确的关联解析。

常见的实践,以及最终Antlr 4参考,让我期待一个左关联解析,对应于下面的侦听器事件跟踪

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

我的语法、我的期望、我对听众事件的解释或其他方面有问题吗?

我认为上面描述的解决方法是一个合适的答案。生成的解析器需要将优先级参数传递给递归调用,由于优先级与令牌相关联,因此令牌必须在递归规则中直接可用,这样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;

相关内容

  • 没有找到相关文章

最新更新