示例代码:
tuple
: '(' expr (',' expr)* ')' // 一般的元组规则
| '(' ')' // 空元组规则
;
expr
: ID // 变量标识符规则
| INT // 整数值规则
| FLOAT // 浮点数值规则
;
上面的元组规则包含一个委托规则(nonterminal),即expr。因此,这个规则不是LL(1)规则,因为它无法为符号表达式(可能是一个标识符、一个整数值或一个浮点数值)准确的进行预测。因此,ANTLR生成识别这个规则的分析器(parser)会失败。
为了解决这个问题,我们可以将委托规则提取为一个子规则,并在元组规则中使用通配符(wildcard)来代替逗号符号,从而生成一个LL(1)规则。
示例代码:
tuple
: '(' exprs? ')' // 通配符规则
;
exprs
: expr (',' expr)* // 独立的表达式规则
;
expr
: ID // 变量标识符规则
| INT // 整数值规则
| FLOAT // 浮点数值规则
;
这个解决方案使用通配符来允许可选的表达式列表,并将表达式列表提取为一个独立的规则。这样,ANTLR将为每个元组规则产生一个唯一的解析动作,以允许其成为LL(1)规则。
注意:这个解决方案代价是冗余的规则,但是这种权衡是必要的,因为