左因子分解与左递归之间的差异

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了左因子分解与左递归之间的差异相关的知识,希望对你有一定的参考价值。

Left FactoringLeft Recursion有什么区别?据我所知,Left factoring是一种预测自上而下的解析技术。但是当我听到这两个术语时,我感到困惑。

答案

左因子分解是去除出现在同一非终端的两个产生中的共同左因子。这样做是为了避免解析器回溯。假设解析器具有预测,请考虑此示例 -

A - > qB | QC 其中A,B,C是非终端,q是句子。在这种情况下,解析器将会混淆选择哪两个产品,并且可能需要回溯。在左保理后,语法转换为 -

A - > qD

D - > B | C

在这种情况下,具有前瞻的解析器将始终选择正确的生产。

左递归是一种情况,当非终端生产中最左边的非终端是非终端本身(直接左递归)或通过一些其他非终端定义,再次重写到非终端(间接)左递归)。考虑这些例子 -

(1)A - > Aq(直接)

(2)A - > Bq B - > Ar(间接)

如果解析器执行自顶向下解析,则必须删除左递归

另一答案

Left Factoring是一种语法转换技术。它包括“分解”两个或多个作品共有的前缀。

例如,从:

A→αβ|一个c

至:

A→αA'

A'→β| ç


Left Recursion是一个语法所具有的属性,只要你可以在一个或多个步骤中从给定变量(非终端)派生以相同变量开头的rhs。

例如:

A→A a

要么

A→B a

B→A c

有一种称为消除左递归的语法转换技术,它提供了一种方法,在给定左递归语法的情况下,生成另一种等效且不递归的语法。


两个术语之间的关系/混淆可能源于这样的事实:在能够为其导出预测性自顶向下解析器之前,两种转换技术可能需要应用于语法。

另一答案

这是我看到使用的两个术语的方式:

  1. 左递归:当一个或多个产品可以从它们自己到达时,其间没有消耗的代币。
  2. 左分解:转换过程,将语法从左递归形式转换为等效的非左递归形式。
另一答案

左因素:

让给定的语法:A - > ab1 | ab2 | AB3

1)我们可以看到,对于每个产品,都有一个共同的前缀,如果我们在这里选择任何产品,则不能确认我们不需要回溯。 2)它是非确定性的,因为我们不能选择任何产品并确保通过制作正确的解析树来达到我们想要的字符串。但是如果我们以一种确定性的方式重写语法并且让我们足够灵活地将其转换为任何可能没有回溯的字符串,那么它将是:

A - > aA',A' - > b1 | B2 | B3

现在如果我们被要求为字符串ab2制作解析树,现在我们不需要回溯。因为我们总是可以在得到A'时选择正确的生产,因此我们将生成正确的解析树。

左递归:

A - > Aa | b这里很明显,如果我们选择第一个产品,A的左边的孩子将永远是A,这是左递归。因为,A一遍又一遍地呼唤自己。从这个语法生成的字符串是:ba *因为这不能用语法...我们通过编写来消除左递归:

A - > bA'A' - > E | aA'现在我们不会离开递归,也可以生成ba *。

另一答案

左递归:如果语法具有非终结符A,则语法是递归的,以便有一个推导A - >Aα| β其中α和β是终端序列和不以A开头的非终结符号。

在设计自顶向下解析器时,如果语法中存在左递归,则解析器将处于无限循环中,这是因为A试图匹配A本身,这是不可能的。我们可以通过重写违规生产来消除上面的左递归。如-

A - >βA'

A' - >αA'|小量

左因子分解:需要左因子分解来消除语法的非确定性。假设一个语法,S - > abS | ASB

这里,S在生产规则中导出相同的终端a(S的两个替代选择),其遵循非确定性。我们可以改写生产以推迟S的决定 -

S - > aS'

S' - > bS |锑

因此,S'可以替换为bS或Sb

另一答案

左递归:=当左手非终端与右手非终端相同时。示例:A-> A&| B,其中&是alpha。我们可以使用重写此生产来删除左递归。

A-> BA'A' - >&A'|€

左因子平均值productn不应该是非确定性的。 。示例:A - >&A |&B |&C

以上是关于左因子分解与左递归之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

poj 1142

Javacc - 使用左因子而不是前瞻来消除选择冲突

对下面文法先消除左递归,并提取左公共因子,再判断其是不是是LL(1)文法。 S->Aab A->SB B->ab

右连接与左连接

LINQ 内连接与左连接

因子个数 --- 递归法 / 遍历法