Parsing 如果LL(1)解析器是非递归的,那么LL(1)语法怎么可能是递归的?

Parsing 如果LL(1)解析器是非递归的,那么LL(1)语法怎么可能是递归的?,parsing,recursion,ll,compiler-construction,Parsing,Recursion,Ll,Compiler Construction,LL(1)解析器是一种非递归的预激活解析器。既然如此,为什么LL(1)语法可以是递归的?这些似乎不一致。我认为您的困惑源于以下事实:这里有几种不同类型的递归 首先,有一个事实,任何可以生成无限多个字符串的CFG——基本上就是您实际想要使用的任何CFG——都必须涉及一些递归。如果没有任何递归,那么只能得到有限多的字符串。从这个意义上讲,这里有CFG递归,其中有一些产生式规则,导致最初的非终结符第二次(或第三次、第四次等)产生 接下来是解析器的实现方式。一些解析器使用递归下降或递归回溯实现。这是一个

LL(1)解析器是一种非递归的预激活解析器。既然如此,为什么LL(1)语法可以是递归的?这些似乎不一致。

我认为您的困惑源于以下事实:这里有几种不同类型的递归

首先,有一个事实,任何可以生成无限多个字符串的CFG——基本上就是您实际想要使用的任何CFG——都必须涉及一些递归。如果没有任何递归,那么只能得到有限多的字符串。从这个意义上讲,这里有CFG递归,其中有一些产生式规则,导致最初的非终结符第二次(或第三次、第四次等)产生

接下来是解析器的实现方式。一些解析器使用递归下降或递归回溯实现。这是一个独立于原始语法是否是递归的设计决策。让我们称之为解析器递归

一般来说,大多数LL(1)解析器的实现不使用解析器递归,而是执行一系列基于表的查找来确定如何驱动解析。然而,许多LL(1)语法中都有CFG递归,但这是独立的

作为一个例子,考虑这个(非常简单)LL(1)语法:

A→ b|cA

注意这里有CFG递归,因为生产→ cA是递归的

扩充语法后,我们得到以下语法:

→ A$

A→ b|cA

以下是上述语法的LL(1)解析表:

     | b  | c  | $
-----+----+----+---
  S  | A$ | A$ | acc
  A  | b  | cA | -
我们可以使用这个解析表来实现(非迭代的)LL(1)解析器,只需跟踪到目前为止的部分匹配,并在需要预测使用哪个产品时随时查阅这个表