以下语法说明了这个问题:
// 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' ) ) )
其中(表示输入标点符号,)表示退出标点符号,为简洁起见省略所有其他规则和清晰度。
通过检查,这个监听器事件的顺序代表一个右关联解析。
通用实践和The Definitive Antlr 4 Reference,引导我期待一个左关联解析,对应于以下监听器事件跟踪
( 'a' ) ( ',' ( 'b' ) ) ( ',' ( 'c' ) )
我的语法,期望,对听众事件的解释或其他方面是否有问题?
答案 0 :(得分: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;