如何从语法中删除间接左递归

时间:2013-11-01 13:13:04

标签: parsing recursion antlr grammar left-recursion

我有一些相互左递归的ANTLR代码:

expr: int_liter
| bool_liter
| char_liter
| str_liter
| pair_liter
| ident
| array_elem
| unary_oper expr
| expr binary_oper expr
| OPEN_PARENTHESES expr CLOSE_PARENTHESES
;

array_elem:  expr  OPEN_BRACKET expr CLOSE_BRACKET ;

有关如何解决此问题的任何想法?

1 个答案:

答案 0 :(得分:1)

ANTLR 4只能处理直接左递归,但是你的语法包含来自规则exprarray_elemexpr的间接左递归。在您的特定语法中解决此问题的最简单方法是将array_elem规则内联到expr规则中,并使用带标签的外部替代方案为expr中的每个备选方案指定有意义的名称

expr
  : int_liter                                # someLabel
  | bool_liter                               # someLabel               
  | char_liter                               # someLabel
  | str_liter                                # someLabel
  | pair_liter                               # someLabel
  | ident                                    # someLabel
  | expr OPEN_BRACKET expr CLOSE_BRACKET     # array_elem
  | unary_oper expr                          # someLabel
  | expr binary_oper expr                    # someLabel
  | OPEN_PARENTHESES expr CLOSE_PARENTHESES  # someLabel
  ;

请注意使用标记的外部替代方法的以下限制:

  1. 没有两个外部替代品可以共享标签,标签不能与任何规则名称匹配;标签在整个语法中必须是唯一的。
  2. 如果标记了一个规则的外部替代方案(例如array_elem替代方案),则必须标记该规则的所有外部替代方案。