如何识别语法是LL(1),LR(0)还是SLR(1)?
如何识别文法是LL(1),LR(0)还是SLR(1)?
任何人都可以请解释它使用这个例子,或任何其他的例子?
X→Yz | 一个
Y→bZ | ε
Z→ε
要检查语法是否为LL(1),一个选项是构造LL(1)parsing表并检查是否有冲突。 这些冲突可以
- 第一/第一冲突,其中两个不同的产品将不得不被预测为非terminal/terminal对。
- 首先/关注冲突,其中预测了两种不同的产品,其中一种表示应当进行一些生产并扩展到非零数量的符号,另一种表示应该使用生产,表示一些非terminal应该最终扩展到空的string。
- 跟随/关注冲突,其中两个生产指示非终结符最终应该扩展为空string彼此冲突。
让我们通过为每个非终结者build立FIRST和FOLLOW集来试试你的语法。 在这里,我们明白了
FIRST(X) = {a, b, z} FIRST(Y) = {b, epsilon} FIRST(Z) = {epsilon}
我们也有跟随集合
FOLLOW(X) = {$} FOLLOW(Y) = {z} FOLLOW(Z) = {z}
由此,我们可以build立下面的LL(1)parsing表:
abz $ X a Yz Yz Y bZ eps Z eps
由于我们可以build立没有冲突的parsing表,语法是LL(1)。
要检查语法是LR(0)还是SLR(1),我们首先构build语法的所有LR(0)configuration集。 在这种情况下,假设X是您的开始符号,我们得到以下结果:
(1) X' -> .X X -> .Yz X -> .a Y -> . Y -> .bZ (2) X' -> X. (3) X -> Yz (4) X -> Yz. (5) X -> a. (6) Y -> bZ Z -> . (7) Y -> bZ.
由此我们可以看出,语法不是LR(0),因为在状态(1)和(6)中存在移位/减less冲突。 具体而言,因为我们有减less项目Z→。 和Y→。,我们不知道是否将空string减less到这些符号或者移动其他符号。 更一般地说,没有ε生成语法是LR(0)。
但是,这个语法可能是SLR(1)。 为了看到这一点,我们增加了每个减less与特定的非terminal设置的前瞻。 这给了这组SLR(1)configuration集合:
(1) X' -> .X X -> .Yz [$] X -> .a [$] Y -> . [z] Y -> .bZ [z] (2) X' -> X. (3) X -> Yz [$] (4) X -> Yz. [$] (5) X -> a. [$] (6) Y -> bZ [z] Z -> . [z] (7) Y -> bZ. [z]
现在,我们没有更多的减less冲突。 状态(1)中的冲突已被消除,因为我们只有当前瞻是z时才减less,这与其他任何项目都不冲突。 同样,(6)中的冲突也出于同样的原因。
希望这可以帮助!
如果你没有第一个/第一个冲突,也没有FIRST / FOLLOW冲突,你的语法是LL(1)。
FIRST / FIRST冲突的一个例子:
S -> Xb | Yc X -> a Y -> a
通过仅看到第一个input符号a,就不能知道是否应用生产S→Xb或S→Yc,因为a在X和Y的第一组中。
FIRST / FOLLOW冲突的一个例子:
S -> AB A -> fe | epsilon B -> fg
通过只看到第一个input符号f,你不能决定是否应用产量A – > fe或A-> epsilon,因为f在A的FIRST集合和A的FOLLOW集合(A可以被parsing为epsilon B为f)。
请注意,如果您没有epsilon-productions,则不能有FIRST / FOLLOW冲突。
简单的答案:如果关联的LL(1)parsing表在每个表项中具有最多一个生产,则称语法为LL(1)。
Take the simple grammar A -->Aa|b.[A is non-terminal & a,b are terminals] then find the First and follow sets A. First{A}={b}. Follow{A}={$,a}. Parsing table for Our grammar.Terminals as columns and Nonterminal S as a row element. ab $ -------------------------------------------- S | A-->a | | A-->Aa. | --------------------------------------------
由于[S,b]包含两个制作,所以对于select哪个规则存在混淆。因此不是LL(1)。
一些简单的检查,看看文法是LL(1)还是不。 检查1 :语法不应该被recursion。 例如:E – > E + T。 不是LL(1),因为它是左recursion的。 检查2 :应该留下语法。
当两个或两个以上的文法规则select共用一个共同的前缀string时,左分解是必需的。 例如:S – > A + int | A。
检查3 :语法不应该模棱两可。
These are some simple checks.
LL(1)语法是可以由LL(1)parsing器parsing的上下文无关的无歧义语法。
在LL(1)
- 首先L代表从左到右的扫描input。 第二个L代表最左派生。 1代表每个步骤使用一个input符号。
对于检查语法是LL(1)你可以绘制预测分析表。 如果你在表中find多个条目,那么你可以说语法不是LL(1)。
他们也是捷径来检查语法是否是LL(1)。 捷径技术