【发布时间】:2018-07-16 16:37:59
【问题描述】:
LL(1) 解析器是非递归预测解析器。鉴于此,为什么 LL(1) 语法可以是递归的?这些似乎彼此不一致。
【问题讨论】:
标签: parsing recursion ll compiler-construction
LL(1) 解析器是非递归预测解析器。鉴于此,为什么 LL(1) 语法可以是递归的?这些似乎彼此不一致。
【问题讨论】:
标签: parsing recursion ll compiler-construction
我认为您的困惑源于这里有几种不同类型的递归。
首先,任何可以生成无限多字符串的 CFG(基本上是您实际想要在实践中使用的任何 CFG)都必须涉及一定数量的递归。如果没有任何递归,你只能得到有限多个字符串。所以从这个意义上说,有 CFG 递归,其中存在导致原始非终结符在第二次(或第三次、第四次等)时间产生的产生式规则。
接下来是解析器的实现方式。一些解析器是使用递归下降或递归回溯实现的。这是一个与原始语法是否递归不同的设计决策。我们称之为解析器递归。
一般来说,大多数 LL(1) 解析器都被实现为不使用 解析器递归,而是执行一堆基于表的查找来确定如何驱动解析。但是,许多 LL(1) 语法中都有 CFG 递归,但这是分开的。
作为一个例子,考虑这个(非常简单的)LL(1) 语法:
A → b |钙
注意这里有 CFG 递归,因为产生式 A → cA 是递归的。
扩充语法后,我们得到这个语法:
S → 澳元
A → b |钙
这是上述语法的 LL(1) 解析表:
| b | c | $
-----+----+----+---
S | A$ | A$ | acc
A | b | cA | -
我们可以使用此解析表来实现(非迭代)LL(1) 解析器,只需跟踪到目前为止的部分匹配并在我们需要预测要使用哪个产生式时随时查阅此表。
【讨论】: