如何在生产中应用FIRST()规则,例如:
A - > AAb | Ab |小号
其中A是非终端,b,s是终端。
备选方案1&的第一个(A) 2将再次成为A,但是这将以FIRST的无限应用结束,因为我需要一个终端来获得FIRST集?
答案 0 :(得分:1)
要计算FIRST集,通常执行定点迭代。也就是说,你从一小组值开始,然后迭代地重新计算FIRST集,直到集合收敛。
在这种情况下,您首先要注意生产A→s意味着FIRST(A)必须包含{s}。所以最初你设置FIRST(A)= {s}。
现在,您迭代A的每个产品并根据您迄今为止计算的FIRST集的知识更新FIRST。例如,规则
A→AAb
意味着您应该更新FIRST(A)以包含FIRST(AAb)的所有元素。这导致FIRST(A)没有变化。然后你访问
A→Ab
你再次更新FIRST(A)以包括FIRST(Ab),这也是一个无操作。最后,您访问
A→s
由于FIRST(A)已经包含s,因此不会发生任何变化。
由于此次迭代没有任何改变,你最终会得到FIRST(A)= {s},这确实是正确的,因为从A开始的任何推导最终都会产生s
作为其第一个字符。
有关详情,您可能会发现these lecture slides有用(此处为part two)。他们详细描述了自上而下的解析如何工作以及如何迭代计算FIRST集。
希望这有帮助!
答案 1 :(得分:-1)
我的teaching notes是西班牙语,但算法是英文的。这是计算 FIRST 的一种方法:
foreach a ∈ Σ do
F(a) := {a}
for each A ∈ N do
if A→ε ∈ P then
F(A) := {ε}
else
F(A) := ∅
repeat
for each A ∈ N do
F'(A) := F(A)
for each A → X1X2...Xn ∈ P do
if n > 0 then
F(A) := F(A) ∪ F'(X1) ⋅k F'(X2) ⋅k ... ⋅k F'(Xn)
until F(A) = F'(A) forall A ∈ N
FIRSTk(X) := F(X) forall X ∈ (Σ ∪ N)
Σ
是字母表(终端),N
是非终端的集合,P
是生产集(规则),ε
是null字符串,⋅k
是连接到k
个地方的连接。请注意∅ ⋅k x = ∅
,并且连接两个集合会产生笛卡尔积中元素的串联。
手动计算 FIRST 集的最简单方法是每次算法迭代使用一个表。
F(A) = ∅
F'(A) = F(A) ⋅1 F(A) .1 F(b) U F(A) .1 F(b) U F(s)
F'(A) = ∅ ⋅1 ∅ ⋅1 {b} U ∅ ⋅1 {b} U {s}
F'(A) = ∅ U ∅ U {s}
F'(A) = {s}
F''(A) = F'(A) ⋅1 F'(A) .1 F'(b) U F'(A) .1 F'(b) U F'(s)
F''(A) = {s} ⋅1 {s} ⋅1 {b} U {s} ⋅1 {b} U {s}
F''(A) = {s} U {s} U {s}
F''(A) = {s}
我们已经完成了,因为F' = F''
,FIRST = F''
和FIRST(A) = {s}
。
答案 2 :(得分:-2)
您的语法规则已经实现了left recursion和LL解析器are not able to parse grammars with left recursion。
所以你需要首先摆脱左递归,然后你应该能够计算规则的第一组。