注:本题纲白话的总结了所有较难的算法,简单易懂的就省略了
1. NFA转DFA
l 第一步,将正规式转为NFA,例如
即*为自循环
l NFA确定化
l 标号得图
2. 消除直接左递归
若 A->Aa1 | Aa2| b1 | b2
则改写为 A ->b1A` | b2A`
A`->a1A` | a2A`| 空
3. 间接消除左递归
转化为直接再写
例如:
4. Follow集求法
若T->FA 若F后可接空,则将followT加入到followF中
若A→αBβ是一个产生式,则把FIRST(β)的非空元素加入followB
5. Select集
A→α,若α不能推导出ε,则SELECT(A→α)=FIRST(α)
如果α能推导出ε则:SELECT(A→α)=(FIRST(α) –{ε})∪FOLLOW(A)
6. First集求法
首先观察每一个式子有没有->a或->空 或->aB,有则为a
其次处理S->ABD,若A,B可以->空 ,则first S=f A-空 U fB-空 U f D8 ,且 要把f A的 非空终结符加入到S
7. 短语,直接短语,句柄求法
l 画出抽象语法树
l 短语就是同一个根的叶子
l 直接短语就是最后一层的叶子
l 一个短语,直接短语,就是来自于一个根
l 句柄就是直接短语的最左侧的那个
短语:S,(T),b,Sd(T),Sd(T)db,(Sd(T)db)
直接短语:S,(T),b
句柄:S
8. LR(0)分析表
l 分析表分为action表和goto表
l 构造lr0项目集规范组
l 根据项目集画表
9. SLR0分析表
l 求符号的first,follow集
l {X → α.bβ,A → γ.,B →δ.} b为终结符
如果FOLLOW(A)∩FOLLOW(B)∩ {b} =ф,则可以解决冲突
结果:遇到b移进,遇到follow中的,归约
10. LR(1)分析表
l Lr1项目集:1.一开始,绿框处S'是整个句子,所以后面理所当然跟句子结束符#。然后S后面是‘ε’(就是什么都没有)所以β=ε,接着逗号后面是‘#’即a=#,这样FIRST(βa)=FIRST(ε#)={#}。这就是I0中S后面#号的来历。
2.在I2中,如红线所示,在I2:S->a·Ad,#中A的后面是d,所以FIRST(d#)= {d} (就是“d#”的第一个终结符d),所以接下来A的后面跟的是d。
11. 文法类型的判断
l 一型:右侧比左侧长
l 二型:左侧为非终结符
l 三型:式子右侧必为a或aB
12. Ll1文法判断
对于产生式 A-> α | β
1.如果α、β均不能推导出ε(空语句),则 FIRST(α) ∩ FIRST(β) = ∅;
2.α 和 β 至多有一个能推导出 ε;
3. 如果 β经过0步或多步可以推导出 ε,则 FIRST(α) ∩ FOLLOW(A) = ∅
问题 6:
试消除下面文法G[A] 中的左递归和左公因子,并判断改写后的文法是否为LL(1) 文法?
G[A] : A→aABe | a
B→Bb | d
答案:
提取左公共因子和消除左递归后,G[A]变换为等价的G′[A]如下:
A→a A′
A′→A B e|ε
B→d B′
B′→b B′|ε
? 计算非终结符的FIRST 集和FOLLOW集结果如下:
FIRST(A)= { a} FOLLOW(A)= {#,d }
FIRST(B)= { d} FOLLOW(B)= { e }
FIRST(A′)= { a,ε} FOLLOW(A′)= {#,d }
FIRST(B′)= { b,ε} FOLLOW(B′)= { e }
对相同左部的产生式可知:
FIRST (A B e)∩FOLLOW (A′) ={ a }∩ {#,d }= ∅
FIRST (b B′)∩FOLLOW (B′) ={ b }∩ { e }= ∅
所以 G′[S]是 LL(1) 文法。
考虑文法 S→ A S | b A→ S A | a
(1)构造文法的 LR(0)项目集规范族及相应的 DFA。
(3)构造文法的 SLR 分析表。
(4)对于输入串 bab,给出 SLR 分析器所作出的动作。
(5)构造文法的 LR(1)分析表和 LALR 分析表。
答案:
(1)令拓广文法 G’为
(0) S’ → S
(1)S → A S
(2)S→ b
(3)A→ S A
(4)A → a
其 LR(0)项目集规范族及识别该文法活前缀的 DFA 如下图所示:
FOLLOW(S)={#,a,b}
FOLLOW(A)={a,b}
LR(0)项目: