720 likes | 998 Views
第5章 自顶向下语法分析方法. 主要内容. 5.1 确定的自顶向下分析思想 5.2 LL(1) 文法的判别 5.3 非 LL(1) 文法到 LL(1) 文法等 价变换 5.4 不确定的自顶向下分析思想 5.5 确定的自顶向下分析方法. 第 八 讲. 课题: 自顶向下语法分析的基本思想与 LL(1) 文法 目的要求: 1. 理解并掌握 LL(1) 文法的定义; 2. 掌握 first 集合、 follow 集合与 select 集合的求解方法; 教学重点: 1.LL(1) 文法的定义;
E N D
第5章 自顶向下语法分析方法
主要内容 5.1 确定的自顶向下分析思想 5.2 LL(1)文法的判别 5.3 非LL(1)文法到LL(1)文法等 价变换 5.4 不确定的自顶向下分析思想 5.5 确定的自顶向下分析方法
第 八 讲 课题:自顶向下语法分析的基本思想与LL(1)文法 目的要求: 1.理解并掌握LL(1)文法的定义; 2.掌握first集合、follow集合与select集合的求解方法; 教学重点: 1.LL(1)文法的定义; 2.求first集合、follow集合与select集合 教学难点 : 求first集合、follow集合与select集合 教学课时:2 教学方法:多媒体教学 教学内容和步骤 :(如下)
第4章我们学习词法分析,介绍词法分析的工具(主要讲正规文法)和方法(DFA和NFA)。第4章我们学习词法分析,介绍词法分析的工具(主要讲正规文法)和方法(DFA和NFA)。 本章介绍语法分析:在词法分析的基础上,分析句子是否正确。 确定 不确定 自顶向下分析 常用方法 算符优先分析 LR分析(第7章) 自底向上分析
5.1 确定的自顶向下分析思想 1.方法:从开始符号出发,根据当前的单词符号选定产生式替换非终结符往下推导,或者构造一棵语法树。 例1:文法G(S): S→pA S→qB A→cAd A→a 输入串 W=pccadd
S S A A p p c A d 自顶向下的推导过程为: SpA pcAd pccAdd pccadd 相应的语法树:
S S A p A p d c A d c A d c A d c A a
例2:文法G(S)为: S →Ap S → Bq A →a∣cA B→b∣dB 当输入W=ccap推导: 自顶向下的推导过程为: S Ap cAp ccAp ccap
S S p A S A p S c A p A A p c A c A c A c A a 语法树为:
在上述2个例子推导过程中,如何根据输入串的第1个符号来确定产生式呢? 2. 开始符号集合的定义 设G=(VT,VN, P ,S )是上下文无关文法,开始符号集合为First()={ a | aβ,a∈VT, 、β∈V*} 若ε,则规定∈First() 。 * * 所以对于例2中文法G(S)有: FIRST(Ap)={a,c}; FIRST(Bq)={b,d}
例3:文法G[S] : S aA | d A bAS|ε 若输入W=abd,则推导过程为: S aA abAS abS abd
S S A A a a S S b A S A a A a S b A S b A ε d ε 语法树为:
从上例可以看出:第二步推导的产生式该如何确定呢?为此引入后跟符号的集合定义: 3. 后跟符号集合的定义: 设G=(VT,VN,P,S)是上下文无关文法,A∈VN,S是开始符号, Follow(A)={a | S uAβ且a∈VT,a ∈First(β),u∈VT*,β∈V+}。 若S uAβ,且β ε,则#∈Follow(A) (#表示输入串的结束符,或句子括号) * * *
也可以定义为: Follow(A)={a|S…Aa…, a∈VT} 若S…A,则#∈Follow(A)。 * * 换句话说: Follow(A)是所有句型中出现在紧接A之后的终结符或“#”。
例4:在例2中文法G[S]为:S Ap | Bq A a | cA B b | dB 求Follow集。 解:Follow(S)={#} Follow(A)={p} Follow(B)={q}
4. 选择集合的定义 给定上下文无关文法的产生式A,AVN,V*, 若ε,则Select(A)=First(); 若ε,则Select(A)= (First()-{ε})∪Follow(A) * *
5. LL(1)文法的定义: 一个上下文无关文法是LL(1)文法的充分必要条件是对每个非终结符A的两个不同产生式: A,Aβ满足Select(A)∩Select(Aβ)=,其中、β不同时 。 对于LL(1)文法,我们可以采用确定的自顶向下分析方法进行分析。 *
6. LL(1)文法的含义 • 第一个L表示:自顶向下分析是从左向右扫描输入串。 • 第二个L表示:分析过程中将用最左推导。 • 1表示:只需向右看一个符号便可决定如何推导(即选择哪个产生式进行推导)。 • 类似也可以有LL(K)文法:需向前查看K个符号才可确定选用哪个产生式。
例5:上例3文法: SaA|d AbAS|ε 不难看出: Select(Sa A)=First(aA)={a} Select (Sd)= First(d)={d} Select (AbAS)={b} Select (Aε) = (first(ε)-{ε})∪follow(A)={a,d,#} SAa aA ε * SaA abAS abAd S aA abAS abAaA 所以Follow(A)={a,d,#}
不难看出,其中 Select (SaA) ∩Select(Sd) ={a}∩{d}= Select(AbAS) ∩Select(Aε) ={b}∩{a,d,#}= 所以,上述文法是LL(1)文法。
例6:设文法G[S]为: S aAS | b A bA |ε 判别是否是LL(1)文法。
解: Select(S aAS)=first(aAS)={a} Select ( S b ) ={b} Select ( A bA ) ={b} Select ( A ε) =(first(ε)-{ε})∪follow(A)={a,b} Select( SaAS ) ∩Select(Sb ) ={a}∩{ b }= Select(A bA) ∩Select(A ε)={b}∩{a,b} 因此,该文法不是LL(1)文法,因而也就不可以采用确定的自顶向下分析方法。 S aAS aAb S aAS aAaAS
教学总结 语法分析是编译过程中不可缺少的重要阶段,其主要功能是对词法分析生成的单词流进行分析,识别各种语法成分。 语法分析方法有自顶向下和自底向上两种,有自顶向下分析法又有确定和不确定两种。 一个上下文无关文法是LL(1)文法的充分必要条件是对每个非终结符A的两个不同产生式: A,Aβ满足Select(A)∩Select(Aβ)=,其中、β不同时 。 LL(1)文法可以采用自顶向下分析方法。
作 业 教材P99-100练习: 1(1),2(1)
第 九 讲 课题:LL(1)文法的判别 目的要求: 掌握LL(1)文法的判别方法; 教学重点: LL(1)文法的判别 教学难点 : LL(1)文法的判别 教学课时:2 教学方法:多媒体教学 教学内容和步骤 :(如下)
5.2 LL(1)文法的判别 • 对于一个经过压缩(即不含有多余规则)的文法G[S],判别其是否为LL(1)文法的步骤: • 求出能推出ε的非终结符 • 计算FIRST集 • 计算FOLLOW集 • 计算SELECT集 • 判别是否是LL(1)文法
下面我们通过一个例子来分析判别过程。 例:若文法G[S]为: S AB | bC A ε | b B ε | aD C AD | b D aS | c 判别文法是否是LL(1)文法。
1. 求出能推出ε的非终结符 S→AB S→bC A→ε A→bB→ε B→aD C→AD C→bD→aS D→c
2. 计算first集: • 方法一:根据定义计算 • 对于任一文法符号xV,计算first(x) : • 若xVT,则first(x)={x} • 若xVN,且有xa…,aVT,则afirst(x) • 若xVN,x ,则first(x)
若xVN,y1,y2,…,yi都VN,产生式xy1y2…yn,当y1,y2,…yi-1都时(1≤i≤n),若xVN,y1,y2,…,yi都VN,产生式xy1y2…yn,当y1,y2,…yi-1都时(1≤i≤n), • 则first(y1)-{}, first(y2)-{},…, first(yi-1)-{},first(yi)都包含在first(x)中。 • e) 当上式中所有yi (1≤i≤n), • 则first(x)=first(y1) ∪first(y2) ∪…∪first(yn) ∪ {} * *
按上述规则可求得文法中各非终结符的first集合:按上述规则可求得文法中各非终结符的first集合: first(S)={first(A)-{}} ∪{first(B)-{}} ∪{} ∪{b}={a,b, } first(A)={b} ∪{}={b, } first(B)={} ∪{a}={a, } first(C)={first(A)-{}} ∪first(D) ∪first(b) ={a,b, c} first(D)={a} ∪{c}={a,c}
任一符号串的first集合的计算方法: 如果文法符号串V*, =X1X2…Xn, 1. 当X1ε,则first()=first(X1) 2. 当对任何j(1≤j≤i-1,2 ≤i ≤n),εfirst(Xj) 则first()=(first(X1)-{ε}) ∪(first(X2)-{ε}) ∪…∪(first(Xi-1)-{ε}) ∪first(Xi ) 3. 当first(Xj)都含有ε时(1 ≤j ≤ n),则first()=first(X1) ∪first(X2) ∪…∪first(Xj) ∪{ε} *
根据上述规则,每个产生式的右部符号串开始符号集合为:根据上述规则,每个产生式的右部符号串开始符号集合为: first(AB)=first(A) ∪first(B) ∪{ε}={a, b, ε} first(bC)={b} first(ε)={ ε} first(aD)={a} first(AD)=(first(A)-{ε}) ∪first(D)={a,b,c} first(b)={b} first(aS)={a} first(c)={c}
3. 计算Follow 集: 方法一:根据定义计算 算法如下: (1)设S为开始符号,则#follow(S); (2)若A→αBβ是一个产生式,则把FIRST(β)或{}加至FOLLOW(B)中; (3)若A→αB是一个产生式,或A→αBβ是一个产生式而β(即FIRST(β)),则把 FOLLOW(A)加至FOLLOW(B)中. 即:Follow(A)是所有句型中出现在紧接A之后的终结符或“#”。 *
文法为: S AB | bC A ε | b B ε | aD C AD | b D aS | c Follow(S)={#} Follow(A)={a,#,c} Follow(B)={#} Follow(C)={#} Follow(D)={#} S为开始符号,#加入follow(S)中。 S AB B Bb A AaD S AB A A AB AaD bC bADbAc
(3) 计算Select集: 每个产生式的Select集合计算为: Select(SAB)= first (AB)∪Follow(S)={b,a,#} Select(S bC)= first (bC)={b} Select(Aε)= first (ε)∪Follow (A)={c,a,#} Select(Ab)= first (b) ={b } Select(Bε)= first (ε) ∪Follow (B)={ #} Select(BaD)= first (aD) ={a} Select(CAD)= first (AD) ={b,a,c}
Select(CAD)= first (AD) ={b,a,c} Select(Cb)= first (C) ={b } Select(DaS)= first (aS) ={ a } Select(Dc)= first (c) ={c}
所以select的交集为: Select(SAB) ∩Select (SbC)= {b} ≠ Select(Aε) ∩ Select (Ab)= Select(Bε) ∩ Select (BaD)= Select(CAD) ∩ Select (Cb)= {b} Select(DaS) ∩ Select (Dc)= 因此该文法不是LL(1)文法。
教学总结 对于一个经过压缩(即不含有多余规则)的文法G[S],判别其是否为LL(1)文法的步骤: 求出能推出ε的非终结符 计算FIRST集 计算FOLLOW集 计算SELECT集 判别是否是LL(1)文法
作 业 教材P100练习: 2(2),3
第 十 讲 课题:某些非LL(1)文法到LL(1)文法的等价变换 目的要求: 掌握非LL(1)文法到LL(1)文法的等价变换方法; 教学重点: 非LL(1)文法到LL(1)文法的等价变换 教学难点 : 非LL(1)文法到LL(1)文法的等价变换 教学课时:2 教学方法:多媒体教学 教学内容和步骤 :(如下)
5.3 某些非LL(1)文法到LL(1)文法的等价变换 由LL(1)文法的定义可知,若文法中含有直接或间接左递归,或者含有左公共因子,该文法肯定不是LL(1)文法,要进行变换。当然并不是所有的非LL(1)文法都可以变换为LL(1)文法。 • 转换方法: • 提取左公共因子 • 消除左递归
一. 提取左公共因子 • 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
例:文法G1[S] 为:S→aSbS→aSS→ε 显然, G1'仍然不是LL(1)文法。因此,文法中不含左公共因子只是LL(1)文法的必要条件。 提出共因子变换为:S→aS(b|ε)S→ε 可以用实例验证,已知串w=aabb,推导如下: S=>aSA =>aaSAA =>aaAA =>aabA (aaA) 也可以用定义判别(练习) 进一步变换为G1' :S→aSA A→b A→ε S→ε
例:已知文法G2如下:(公因子隐式)A→ad A→BcB→aA B→bB 第三步G2' : A→aA' A→bBc A'→d A'→Ac B→aAB→bB 转换步骤如下: 第二步: A→a(d|Ac) A→bBc B→aAB→bB 第一步:A→ad A→aAc A→bBc B→aAB→bB 显然,结果G2'是LL(1)文法。(练习)
经过文法提取左公共因子后的文法,若有多余的产生式,则必须进行化简 。 • 例:文法G3[S] 为:S→aSd S→Ac A→aS A→b 转换步骤如下: 第三步G3' : S→aSA' S→bc A'→d A'→c A→aSA→b 第一步:S→aSdS→aSc S→bc A→aSA→b 第二步: S→aS(d|c)S→bc A→aSA→b 不难发现,G3'中A是不可达到的符号,应化简。
例:文法G4[S] 为:S→Ap|Bq A→aAp|d B→aBq|e 转换步骤如下: 第一步:S→aApp|aBqq|dq|eqA→aAp|dB→aBq|e 第二步: S→a(App|Bqq)S→dq|eq A→aAp|dB→aBq|e
第三步: S→aS' S→dq|eq S'→App|BqqA→aAp|dB→aBq|e 第四步: S→aS' S→dq|eq S'→ aAppp|aBqqq|dpp|eqqA→aAp|dB→aBq|e 可见,对于文法G4[S]利用提取左公共因子无法在有限步骤内替换成无左公共因子的文法。
结论 • 不一定每个文法的左公共因子都能在有限的步骤内替换成无左公共因子的文法。 • 一个文法提取了左公共因子后,只解决了相同左部产生式右部的FIRST集不相交问题,当改写后的文法不含空产生式,且无左递归时,则改写后的文法是LL(1)文法,否则还需用LL(1)文法的判别方式进行判断才能确定是否为LL(1)文法。
二. 消除左递归 • 直接左递归:A→Aβ AVN, β V* • 间接左递归:A→Bβ B→Aα A,BVN, α,β V*