第5章 自顶向下语法分析方法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理
S→AB S→bC A→ε A→b B→ε B→aD C→AD C→b D→aS D→c
FIRST(S)=(FIRST(A)-{ε})∪FIRST(B){ε})∪{ε}∪{b}={a,b,ε} FIRST(A)={b, ε} FIRST(B)={a, ε} FIRST(C)={a,b,c}
编译原理
第5章 自顶向下语法分析方法 确定的自顶向下分析思想 LL(1)文法的判别 某些非LL(1)文法到LL(1)文法的等 价变换 不确定的自顶向下分析思想 确定的自顶向下分析方法
Hale Waihona Puke Baidu译原理
语法分析:检查源程序的语法错误,并生成相应的中间 形式,以供下一阶段使用。
确定的分析方法: LL(1)文法才适用
编译原理
3. 选择集合 SELECT(A →α)
给定上下文无关文法的产生式A→α,A∈VN , α∈V*, * 若α ε,则SELECT(A→α)=FIRST(α) * 若α ε,则 SELECT(A→α)=(FIRST(α)-{ε}) ∪FOLLOW(A)
编译原理
练习 文法G[S]: S→eT | RT T→DR | ε R→dR | ε D→a | bd 求:FIRST(S)、FIRST(T)、FIRST(D) FOLLOW(T)、FOLLOW(R)、FOLLOW(D) 以及每个产生式的SELECT集合
W=abd试图推导的过程: S aA abAS abS abd
编译原理
二、定义
1. 开始符号集FIRST(α) 设 G = (VT ,VN , S , P) 是上下文无关文法, * FIRST(α) = {a|α aβ,a∈ VT,α,β ∈ V*} * 若α ε,则规定ε∈FIRST(α)
编译原理
2. 文法 G2[S]: S→Ap S→Bq A→a A→cA B→b B→dB
W=ccap自顶向下的推导过程:
S Ap cAp ccAp ccap
语法树: S A p c A A S p c c A A A S p c c A A A a S p
编译原理
文法G2[S]: S→Ap S→Bq A→a A→cA B→b B→dB
所以该文法是LL(1)文法。
编译原理
• 练习2 设文法G[S] 为: S→aAS S→b A→bA A→ε
SELECT(S→aAS) SELECT(S→b) SELECT(A→bA) SELECT(A→ε) ={a} ={b} ={b} ={a,b}
SELECT(S→aAS) ∩ SELECT(S→b)={a}∩{b}=Φ SELECT(A→bA)∩SELECT(A→ε)={b}∩{a,b}≠Φ
• 文法 G1[S]: S→pA S→qB A→cAd A→a B→dB B→b
语法树: S p A p S A c A d p S A c A d c A d p S A c A d c A d a
编译原理
• 文法G1[S]: S→pA S→qB A→cAd A→a B→dB B→b
这个文法的特点: 1. 每个产生式的右部都由终 结符号开始。 2. 如果两个产生式有相同的 左部,那么它们的右部由 不同的终结符开始。
这个文法的特点: 1. 每个产生式的右部不全是 由终结符号开始。 2. 如果两个产生式有相同的 左部,那么它们的右部由 不同的终结符或非终结符 开始。 3. 文法中无空产生式。
编译原理
3. 文法G3[S]: S→aA S→d A→bAS A→ε
产生式中有A→ε的形式,当 A的非空产生式不能与相应 字符匹配时,考虑用A→ε, 且后面字符的产生式可与该 字符匹配,其匹配惟一时, 也为确定文法。
编译原理
S→AB S→bC A→ε A→b B→ε B→aD C→AD C→b D→aS D→c
FOLLOW(S)={#}∪FOLLOW(D)
FOLLOW(A)={a}∪{a,c}∪FOLLOW(S)
FOLLOW(B)=FOLLOW(S) FOLLOW(C)=FOLLOW(S) FOLLOW(D)=FOLLOW(B)∪FOLLOW(C) FOLLOW(S)= {#} FOLLOW(A)= {a,c,#} FOLLOW(B)= {#}
FIRST(D)={a,c}
编译原理
3.计算FOLLOW集 • 1.对于文法的开始符号S,置#于FOLLOW(S); • 2.若A→αBβ是一个产生式,则把 FIRST(β )-{}加至FOLLOW(B)中; • 3.若A→αB是一个产生式,或A→αBβ是 * 一个产生式而β (即FIRST(β )),则把 FOLLOW(A),加至FOLLOW(B)中.
FIRST(S)={a,b,ε} FIRST(A)={b, ε} FIRST(B)={a, ε} FIRST(C)={a,b,c} FIRST(D)={a,c} FIRST(AB)={a,b,ε} FIRST(AD)={a,b,c} FOLLOW(S)= {#} FOLLOW(A)= {a,c,#} FOLLOW(B)= {#} FOLLOW(C)= {#}
编译原理
1.求出能推出ε的非终结符
S→AB S→bC A→ε A→b B→ε B→aD C→AD C→b D→aS D→c
非终结符 初值 第一次扫描 第二次扫描 是
S
A 是
B 未定 是
C 未定
D 未定 否
未定 未定
否
编译原理
2.计算FIRST集
• 1.若XV,则FIRST(X)={X} • 2.若XVN,且有产生式Xa…,则a∈FIRST(X); 若X也是一条产生式,则∈FIRST(X). • 3.若XY…是一个产生式且YVN,则把FIRST(Y)中 的所有非元素都加到FIRST(X)中; 若X Y1Y2…YK 是一个产生式,Y1,Y2,…,Y(i-1)都 是非终结符,而且,对于任何j,1≤j ≤i-1,FIRST(Yj) * 都含有(即Y1..Y(i-1) ),则把FIRST(Yj)中的所有 非元素都加到FIRST(X)中;特别是,若所有的 FIRST(Yj , j=1,2,…,K)均含有,则把加到FRIST(X) 中。
编译原理
4. LL(1)文法 一个上下文无关文法是LL(1)文法的充 要条件是: 对每个非终结符A的两个不同产生式 A→α和A→β,满足 SELECT(A→α)∩SELECT(A→β)=Φ * 其中α,β不同时能 ε。
编译原理
LL(1)文法的含义:
第一个L表示:自顶向下分析是从左向右扫描 输入串。 第二个L表示:分析过程中将用最左推导。 1表示:只需向右看一个符号便可决定如何推 导(即选择哪个产生式进行推导)。 类似也可以有LL(K)文法:需向前查看K个符号 才可确定选用哪个产生式。
编译原理
一、提取左公共因子 A→αβ|αγ SELECT(A→αβ)∩ SELECT(A→αγ)≠Φ,因 此非LL(1)文法。 等价变换为A→α(β|γ),然后: A→αA' A' → β|γ A→αβ1|αβ2|…|αβn 变换为A→α(β1|β2|…|βn) , 然后: A→αA' A' → β1|β2|…|βn
编译原理
• 文法G2[S]: S→Ap S→Bq A→a A→cA B→b B→dB
• FIRST(Ap)={a,c} • FIRST(Bq)={b,d}
相同左部产生式,其右部 的FIRST集合不相交时,可 确定其分析过程。
编译原理
2. 后跟符号集 FOLLOW(A) 设 A∈VN , S是开始符号 FOLLOW(A) = {a|S * A且a∈FRIST(), * ∈VT ,∈V+ } 若S * A,且 * ε,则规定 #∈FOLLOW(A) * 即:FOLLOW(A)={a|S …Aa… ,a∈VT} * 若S …A,则规定 #∈FOLLOW(A)
编译原理
• 例:文法G2为: A→ad 1.化为: A→Bc A→ad B→aA A→aAc B→bB A→bBc B→aA B→bB
结果是LL(1)文法。
2.化为: A→a(d|Ac) A→bBc B→aA B→bB
3.化为: A→aA' A→bBc A'→d A'→Ac B→aA B→bB
编译原理
• 例:文法G1[S] 为: S→aSb S→aS S→ε
w=aabb S=>aSA =>aaSAA =>aaAA =>aabA (aaA)
化为: S→aS(b|ε) S→ε 进一步化为: S→aSA A→b A→ε S→ε
结果仍然不是LL(1)文法。 因此,文法中不含左公共因子只是LL(1)文法的必要条件。 转换后的文法右部包含ε时,应判断是否LL(1)文法。
编译原理
S→AB S→bC A→ε A→b B→ε B→aD C→AD C→b D→aS D→c
SELECT(S→AB)={a,b,#} SELECT(S→bC)={b} SELECT(A→ε)={a,c,#} SELECT(A→b)={b} SELECT(B→ε)={#} SELECT(B→aD)={a} SELECT(C→AD)={a,b,c} SELECT(C→b)={b} SELECT(D→aS)={a} SELECT(D→c)={c}
编译原理
5.2 LL(1)文法的判别
1. 2. 3. 4. 5.
求出能推出ε的非终结符 计算FIRST集 计算FOLLOW集 计算SELECT集 判别是否是LL(1)文法
编译原理
• 例:设文法G[S] 为: S→AB S→bC A→ε A→b B→ε B→aD C→AD C→b D→aS D→c 判断它是否是LL(1)文法。
所以该文法不是LL(1)文法。
编译原理
G[S]: S→aAS S→b A→bA A→ε
对输入串W=ab进行推导:
S aAS abAS abS 出错
S aAS aS ab
编译原理
5.3 文法的等价变换
提取左公共因子 消除左递归
一些非LL(1)文法, 可经过提取左公 因子,消除左递归等方法变换为与之等 价的LL(1)文法,其语法分析可用确定的 分析方法。
FOLLOW(C)= {#}
FOLLOW(D)= {#}
编译原理
4.计算SELECT集
给定上下文无关文法的产生式A→α,A∈VN , α∈V*, * 若α ε,则SELECT(A→α)=FIRST(α) * 若α ε,则 SELECT(A→α)=(FIRST(α)-{ε}) ∪FOLLOW(A)
#作为输入串的结束符,或称为句子括号,如: #输入串#
编译原理
如 文法G3[S]: S→aA S→d A→bAS A→ε FOLLOW(S)={#,a,d} FOLLOW(A)={#,a,d}
编译原理
对A→α,A→β其中A∈VN , α, β ∈V*,当α 和β不同时推导出空时(设 α不推导出空,β推 导出空),则当 FIRST(α)∩(FIRST(β)∪FOLLOW(A))=Φ时, 对于非终结符A的替换仍可唯一地确定候选。 如 文法G3[S]: S→aA S→d A→bAS 符合上述条件,所以其分 A→ε 析过程可确定。 FIRST(bAs)={b} FIRST( ε)={ε} FOLLOW(A)={#,a,d}
该文法不是LL(1)文法。
FOLLOW(D)= {#}
编译原理
练习1 文法G[S]是否是LL(1)文法: S→aA S→d A→bAS A→ε
SELECT(S→aA) ={a} SELECT(S→d) ={d} SELECT(A→bAS) ={b} SELECT(A→ε) ={a,d,#} SELECT(S→aA) ∩ SELECT(S→d)={a}∩{d}=Φ SELECT(A→bAS)∩SELECT(A→ε)={b}∩{a,d,#,}=Φ
使 不确定分析方法 用 方 法 自底向上
自顶向下
无限循环 回溯
编译原理
5.1 确定的自顶向下分析思想
从文法开始符号出发,根据当前的输入符号确 定选择哪个产生式替代相应非终结符,直到与输入 符号串完全匹配。(或从根结点构造语法树)
编译原理
一、举例
1. W=pccadd自顶向下的推导过程:
S pA pcAd pccAdd pccadd