Parsing LR(1)项目DFA-计算外观
我很难理解如何计算LR(1)-项的lookahead 假设我有这样的语法:Parsing LR(1)项目DFA-计算外观,parsing,context-free-grammar,lookahead,dfa,lr,Parsing,Context Free Grammar,Lookahead,Dfa,Lr,我很难理解如何计算LR(1)-项的lookahead 假设我有这样的语法: S -> AB A -> aAb | a B -> d LR(1)-项是具有前瞻性的LR(0)项。因此,我们将获得状态0的以下LR(0)-项: S -> .AB , {lookahead} A -> .aAb, {lookahead} A -> .a, {lookahead} 国家:1 A -> a.Ab, {lookahead} A -> a. ,{lo
S -> AB
A -> aAb | a
B -> d
LR(1)-项是具有前瞻性的LR(0)项。因此,我们将获得状态0的以下LR(0)-项:
S -> .AB , {lookahead}
A -> .aAb, {lookahead}
A -> .a, {lookahead}
国家:1
A -> a.Ab, {lookahead}
A -> a. ,{lookahead}
A -> .aAb ,{lookahead}
A ->.a ,{lookahead}
有人能解释一下如何计算lookaheads吗?一般做法是什么
提前感谢LR(1)解析器中使用的lookahead计算如下。首先,开始状态有一个表单项
S -> .w ($)
对于每个产品S->w,其中S是开始符号。在这里,$标记表示输入的结束
接下来,对于包含形式为A->x.By(t)的项的任何状态,其中x是终端和非终端的任意字符串,而B是非终端,您可以为每个产品B->w和集合中的每个终端(yt)添加形式为B->.w(s)的项。(这里,首先是指,在讨论LL解析器时通常会介绍它们。如果您以前没有见过它们,我将花几分钟时间查看这些课堂讲稿)
让我们试试你的语法。我们首先创建一个包含
S -> .AB ($)
接下来,使用我们的第二条规则,对于A的每一个产品,我们添加一个与该产品对应的新项目,并且每个终端的lookaheads位于第一位(B$)。因为B总是产生字符串d,FIRST(B$)=d,所以我们介绍的所有产生式都具有前瞻性d。这给
S -> .AB ($)
A -> .aAb (d)
A -> .a (d)
A -> a.Ab (d)
A -> a. (d)
A -> .aAb (b)
A -> .a (b)
现在,让我们构建对应于在初始状态中看到“a”的状态。我们首先将圆点移动到每个生产的一个步骤上,该步骤以:
A -> a.Ab (d)
A -> a. (d)
现在,由于第一个项在非终结符之前有一个点,我们使用我们的规则为a的每个结果添加一个项,使这些项先行(bd)=b。这给
S -> .AB ($)
A -> .aAb (d)
A -> .a (d)
A -> a.Ab (d)
A -> a. (d)
A -> .aAb (b)
A -> .a (b)
继续此过程最终将为此LR(1)解析器构造所有LR(1)状态。如下所示:
[0]
S -> .AB ($)
A -> .aAb (d)
A -> .a (d)
[1]
A -> a.Ab (d)
A -> a. (d)
A -> .aAb (b)
A -> .a (b)
[2]
A -> a.Ab (b)
A -> a. (b)
A -> .aAb (b)
A -> .a (b)
[3]
A -> aA.b (d)
[4]
A -> aAb. (d)
[5]
S -> A.B ($)
B -> .d ($)
[6]
B -> d. ($)
[7]
S -> AB. ($)
[8]
A -> aA.b (b)
[9]
A -> aAb. (b)
如果有帮助的话,我去年夏天教了一门编译器课程,并且有了。关于自底向上解析的幻灯片应该涵盖LR解析和解析表构造的所有细节,我希望您会发现它们很有用
希望这有帮助 您构建的LR(1)项集应该还有两个项
I8 A-->来自I2的aA.b、b
I9 A-->aAb,b从I8开始,这里是语法的LR(1)自动机,如下所示
我认为更好的理解是尝试绘制自动机,流程将使lookaheads的概念更清晰
我还得到了11个州,而不是8个州:
State 0
S: .A B ["$"]
A: .a A b ["d"]
A: .a ["d"]
Transitions
S -> 1
A -> 2
a -> 5
Reductions
none
State 1
S_Prime: S .$ ["$"]
Transitions
none
Reductions
none
State 2
S: A .B ["$"]
B: .d ["$"]
Transitions
B -> 3
d -> 4
Reductions
none
State 3
S: A B .["$"]
Transitions
none
Reductions
$ => S: A B .
State 4
B: d .["$"]
Transitions
none
Reductions
$ => B: d .
State 5
A: a .A b ["d"]
A: .a A b ["b"]
A: .a ["b"]
A: a .["d"]
Transitions
A -> 6
a -> 8
Reductions
d => A: a .
State 6
A: a A .b ["d"]
Transitions
b -> 7
Reductions
none
State 7
A: a A b .["d"]
Transitions
none
Reductions
d => A: a A b .
State 8
A: a .A b ["b"]
A: .a A b ["b"]
A: .a ["b"]
A: a .["b"]
Transitions
A -> 9
a -> 8
Reductions
b => A: a .
State 9
A: a A .b ["b"]
Transitions
b -> 10
Reductions
none
State 10
A: a A b .["b"]
Transitions
none
Reductions
b => A: a A b .
非常感谢。你能解释一下为什么在下面的语法中,$包含在先行集合中,但它不在第一个($A)中吗?s→ •A{$}A→ • AA{$,b}A→ • bc{$,b}@mrjasmin-我需要了解更多的语法,以了解第一个和前瞻集应该是什么;你能多发一些吗?另外,请注意,您不应该在任何地方首先计算($A)。如果您有一个->.AA($),那么结果项的lookahead将是FIRST(A$)中的终端,而不是FIRST($A)。那有用吗?嗨!这个问题来自一次考试,给出的答案是:S->.A{$}A->.AA{}A->.bc{}学生应该找到前瞻集,答案是上面的帖子。我不明白美元是怎么回事lookahead@mrjasmin-最初的$可能来自于S是开始符号的事实,因此它的产品总是在事实之后标记为$。因此,生产A->.AA最初将有$作为前瞻,A->bc也是如此。接下来,由于A->.AA($)是一个项目,您需要为A的每一个产品添加新项目,首先是lookaheads(A$)。由于A->bc是A的产物,所以第一个(A$)的唯一元素是b。因此,您需要将A->.AA(b)和A->.bc(b)添加到项目集。将它们与A->.AA($)和A->.bc($)合并得到A->.AA($,b)和A->.bc($,b)。这有意义吗?为什么生产A->.AA最初会有美元作为前瞻?A->aAb | A最初不应该也有美元吗?谢谢