1 / 64

编译原理第五章

编译原理第五章. 自顶向下语法分析方法. 语法分析的作用: 识别由词法分析给出的单词符号序列是 否是给定文法的正确句子(程序) 目前语法分析常用的方法 有 自顶向下分析和自底向上分析 。 而自底向上分析又可分为算符优先分析和 LR 分析。 自顶向下分析也称面向目标的分析方法,也就是从文法的 开始符号出发,企图推导出与输入的单词串完全相匹配的 句子,若输入串是给定文法的句子,则必能推出,反之, 必然出错。 自顶向下分析又可分为确定的和不确定的两种。. 5.1 确定的自顶向下分析思想. 确定的自顶向下分析方法,首先要解决从文法的开始符号

terah
Download Presentation

编译原理第五章

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 编译原理第五章 自顶向下语法分析方法

  2. 语法分析的作用:识别由词法分析给出的单词符号序列是语法分析的作用:识别由词法分析给出的单词符号序列是 否是给定文法的正确句子(程序) 目前语法分析常用的方法有自顶向下分析和自底向上分析。 而自底向上分析又可分为算符优先分析和LR分析。 自顶向下分析也称面向目标的分析方法,也就是从文法的 开始符号出发,企图推导出与输入的单词串完全相匹配的 句子,若输入串是给定文法的句子,则必能推出,反之, 必然出错。 自顶向下分析又可分为确定的和不确定的两种。

  3. 5.1 确定的自顶向下分析思想 确定的自顶向下分析方法,首先要解决从文法的开始符号 出发,如何根据当前的输入符号(单词符号)唯一地确定 选用哪个产生式替换相应非终结符往下推导,或构造一棵 相应的语法树。

  4. 例5.1 若有文法G1[S] SpA|qB AcAd|a BdB|b 对于输入 串W=pccadd,自顶向下的推导过程为: S=>pA =>pcAd =>pccAdd =>pccadd,相应的语法树如下: S S S S p A p A p A A p d d c A d c A c A d d c A c A a

  5. 文法的特点: (1)每个产生式的右部都由终结符号开始。 (2)如果两个产生式有相同的左部,那么它们 的右部由不同的终结符开始。

  6. 例5.2 若有文法G2[S]为: SAp SBq Aa AcA Bb BdB 对于输入串W=ccap,其推导过程为: S=>Ap =>cAp =>ccAp =>ccap 对应的语法树为: S S S S A p A p A p A p c A c A c A c A c A a

  7. 例5.2文法的特点: (1)产生式右部不全是由终结符开始。 (2)如果两个产生式有相同的左部,它们的右部 是由不同的终结符或非终结符开始。 (3)文法中无空产生式。

  8. 定义5.1 设文法G是上下文无关文法 FIRST(α)={a| α=*> aβ,a∈VT*,α,β ∈V*} 若α=*>ε,则规定ε ∈FIRST( α) 对于文法G2 有 文法G2[S]为: SAp SBq Aa AcA Bb BdB FIRST(Ap)={a,c} FIRST(Bq)={b,d}

  9. 例5.3 若有文法G[S] SaA Sd AbAS Aε 若输入串w=abd 其推导过程为: S=>aA =>abAS =>abS =>abd S S S S a A a A a A a A A S b A S A S b b ε d ε

  10. 当某一非终结符的产生式中含有空产生式时,它的非空当某一非终结符的产生式中含有空产生式时,它的非空 产生式的右部首符号集两两不相交,并与在推导过程中紧 跟该非终结符右边可能出现的终结符集也不相交,则仍可 构造确定的自顶向下分析。

  11. 定义5.2 设文法G是上下文无关文法,A∈VN,S是开始符号 FOLLOW(A)={a|S=*>μAβ,且a∈VT,a ∈FIRST(β), μ ∈VT*, β ∈V+} 若S=*> μAβ,且β=*>ε则# ∈FOLLOW(A)。 若有S=*> …A,则规定# ∈FOLLOW(A)

  12. 定义 5.3 给定上下文无关文法产生式Aα,A∈VN, α ∈V*,若α≠*>ε,则 SELECT( Aα)=FIRST( α) 如果α=*>ε,则 SELECT( Aα)=(FIRST( α)-{ε})∪FOLLOW(A)

  13. 定义5.4 一个上下文无关文法是LL(1)文法的充要条件是: 对于每个非终结符A的两个不同产生式Aα,Aβ,满足: SELECT( Aα)∩ SELECT( A β)=Ø 其中α、β不同时能=*>ε LL(1)文法的含义:第一个L表明自顶向下分析是从左到右 扫描字符串,第二个L表明分析过程中将用最左推导,1表 明只需向右看一个符号,便可决定如何推导,即选择哪个产 生式(规则)进行推导。

  14. 例5.3 的文法G[S] 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)=Ø SELECT(AbAS) ∩SELECT(Aε)={a,d,#} =Ø 因此它是一个LL(1)文法。

  15. 例5.4 设文法G[S]为: SaAS Sb AbA Aε 则: SELECT( SaAS)={a} SELECT(Sb) ={b} SELECT(AbA)={b} SELECT(Aε)={a,b} 所以: SELECT( SaAS) ∩SELECT(Sb)=Ø SELECT(AbA) ∩ SELECT(Aε) ≠Ø 因此,它不是LL(1)文法.

  16. 5.2 LL(1)文法的判断 • 通过求FIRST、FOLLOW、SELECT集合进行判断。

  17. 例5.5 若文法G[S]为: SAB SbC Aε Ab B ε BaD CAD Cb DaS Dc

  18. 1、求出能导出ε的非终结符 (1)将数组X[ ]中对应每一非终结符的标记置初值为“未定” (2)扫描文中的产生式 (a)删除所有右部含有终结符的产生式,若这使得以 某一非终结符为左部的所有产生式都被删除,则将数组中对 应该非终结符的标记值改为“否”,说明该非终结符不能推出ε。 (b)若某一非终结符的某一产生式右部为ε,则将数组 中对终结符的标志置为“是”,并从文法中删除该非终结符的所 有产生式。 (3)扫描产生式右部的每一符号 (a)若所扫描到的非终结符号在数组中对应的标志是 “是”,则删去该非终结符,若这使产生式右部为空,则对产 生式左部的非终结符在数组中对应的标志改为“是”,并删除该 非终结符为左部的所有产生式。

  19. (b)若所扫描到的非终结符号在数组中对应的标志是(b)若所扫描到的非终结符号在数组中对应的标志是 “否”,则删除该产生式,若这使产生式左部非终结符的有关产 生式都被删除,则把数组中该非终结符对应的标志改为“否”。 (4)重复(3),直到扫描完一遍文法的产生式,数组中 非终结符对应的特征再没有改变为止。

  20. 2、计算FIRST集 (1)根据定义计算 定义: 定义5.1 设文法G是上下文无关文法 FIRST(α)={a| α=*> β,a∈VT*,α,β ∈V*} 若α=*>ε,则规定ε ∈FIRST( α)

  21. 对于每一文法符号X∈V,计算FIRST(X) • 若X ∈VT,则FIRST(X)={X} • 若X ∈VN,且有产生式Xa...,a ∈ VT则a ∈ FIRST(X) • 若X ∈VN ,Xε,则ε ∈ FIRST(X) • 若X ∈VN ,Y1,Y2...Yi都∈VN,而有产生式 • XY1Y2...Yn。当Y1,Y2...Yi-1都=*>ε时,(其中1≤i≤n), • 则FIRST(Y1)-{ε},... FIRST(Yi-1)-{ε}, FIRST(Yi)都 • 包含在FIRST(X)中。 • (e) 当(d)中所有Y1 ε,则 • FIRST(X)=FIRST(Y1)∪ FIRST(Y2)... ∪ FIRST(Yn) ∪ {ε} • 反复使用(b)~(e),直到每个符号的FIRST集合不再增大为止。

  22. 对于符号串求FIRST集合 若符号串α∈V*, α=X1X2...Xn 当X1不能=*>ε,则置FIRST( α)=FIRST(X1) 若对任何j (1≤j≤i-1,2 ≤i ≤n), ε ∈FIRST(Xj) 则FIRST( α)=∪(FIRST(Xj)-{ε }) ∪FIRST(Xj)

  23. 例5.5 若文法G[S]为: 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} ={b,a, ε } FIRST(A)= {ε } ∪{b}= {b, ε } FIRST(B)= {ε } ∪{a}= {a, ε } FIRST(C)={FIRST(A)- {ε } } ∪ FIRST(D) ∪FIRST(b)={b,a,c} FIRST(D)={a} ∪{c}={a,c} 每个产生式的右部符号串开始符号集合为: FIRST(AB)={a,b, ε} FIRST(bC)={b} FIRST(ε)={ε} FIRST(b)={b} FIRST(aD)=a

  24. FIRST(AD)={a,b,c} FIRST(b)={b} FIRST(aS)={a} FIRST(c)={c}

  25. (2)由关系图法求文法符号的FIRST集 • 每个文法符号对应图中一个结点,对应终结符的结点时, • 用符号本身标记,对应非终结符的结点用FIRST(A)标记。 • (b)如果文法中有产生式AαXβ,且α=*>ε,则对应A的结点到 • 对应X的结点连一条弧线。 • (c) 凡是从FIRST(A)结点有路径可达的终结符结点所标记 • 的终结符都为FIRST(A)的成员。 • (d) 由判别步骤1确定ε是否为某终结符FIRST集的成员,若是, • 则将ε加入该非终结符的FIRST集。

  26. 例5.5 若文法G[S]为: SAB SbC Aε Ab B ε BaD CAD Cb DaS Dc FIRST(C) b FIRST(A) FIRST(S) FIRST(B) FIRST(D) a c

  27. 由关系图可以算出 FIRST(S)={b,a,ε} FIRST(A)={b ,ε} FIRST(B)={a, ε} FIRST(C)={a,b,c} FIRST(D)={a,c}

  28. 3、计算FOLLOW集 • (1)根据定义计算 • 对文法中每一A∈VN计算FOLLOW(A) • 设S为文法中开始符号,把{#}加入FOLLOW(S)中 • 若AαBβ是一个产生式,则把FIRST( β)的非空元素 • 加入FOLLOW(B)中。如果β=*>ε,则把FOLLOW(A) • 也加入FOLLOW(B)中。 • (c) 反复使用(b),直到每个非终结符的FOLLOW集不再 • 增大为止。

  29. 例5.5 若文法G[S]为: SAB SbC Aε Ab B ε BaD CAD Cb DaS Dc FOLLOW(S)={#} ∪FOLLOW(D) FOLLOW(A)=(FIRST(B)-{ε}) ∪FOLLOW(S) ∪FIRST(D) FOLLOW(B)=FOLLOW(S) FOLLOW(C)=FOLLOW(S) FOLLOW(D)=FOLLOW(B) ∪FOLLOW(C)

  30. (2)用关系图法求非终结符的FOLLOW集 • 文法G中的每个符号和“#”对应图中的一个结点,对应终结 • 符和“#”的结符号本身标记。对应非终结符的结点则用 • FOLLOW(A)或FIRST(A)标记。 • (b) 从开始符号S的FOLLOW(S)结到“#”号的结点连一条弧线。 • (c) 如果文法中有产生式AαBβX,且β=*>ε,则从FOLLOW(B) • 结点到FIRST(X)结点连一条弧,当X∈VT时,则与X相连。 • (d) 如果文法有产生式A αBβ,且β=*>ε,则从FOLLOW(B) • 结点到FOLLOW(A)结点连一条弧线。 • (e) 对每一FIRST(A)结点,如果有产生式A αXβ,且α=*>ε, • 则从FIRST(A)到FIRST(X)连一条弧线。 • (f) 凡是从FOLLOW(A)结点有路径可达的终结符或“#”号的 • 结点,其所标记的终结符或“#”号即为FOLLOW(A)的成员。

  31. # FOLLOW(B) FOLLOW(S) FOLLOW(D) FOLLOW(A) FIRST(B) FOLLOW(C) FIRST(D) c a

  32. 计算结果: FOLLOW(S)={#} FOLLOW(A)={a,c,#} FOLLOW(B)={#} FOLLOW(C)={#} FOLLOW(D)={#}

  33. 4、计算SELECT集 (按定义计算) SELECT(SAB)=FIRST(AB)- {ε }∪FOLLOW(S)={b,a,#} SELECT(SbC)=FIRST(bC)={b} SELECT(Aε)=FIRST(ε) - {ε }∪FOLLOW(A)={a,c,#} SELECT(Ab)=FIRST(b)={b} SELECT(B ε)= FIRST(ε) - {ε }∪FOLLOW(B)={#} SELECT(BaD)=FIRST(aD)={a} SELECT(CAD)=FIRST(AD)={a,b,c} SELECT(Cb)=FIRST(b)={b} SELECT(DaS)=FIRST(aS)={a} SELECT(Dc)=FIRST(c)={c}

  34. 从而有: SELECT(SAB) ∩SELECT(SbC) ≠Ø SELECT(Aε) ∩SELECT(Ab) =Ø SELECT(B ε) ∩SELECT(BaD) =Ø SELECT(CAD) ∩SELECT(Cb) ≠Ø SELECT(DaS) ∩SELECT(Dc) =Ø 所以该文法不是LL(1)文法。

  35. 5.3 某些非LL(1)文法到LL(1)文法的等价变化 若文法中含有直接或间接左递归,或含有左公共因子, 则该文法肯定不是LL(1)文法。 等价变换过程实际上就是设法消除文法中的左递归,提取 左公共因子。

  36. 1、提取左公共因子 对于文法中含有形如:Aαβ|αγ的产生式,会使得FIRST集 相交,即有SELECT( Aαβ)∩ SELECT( Aα γ)≠Ø 则将Aαβ|αγ变为: A α (β|γ) 即有:A α A’ A’ β|γ 写成一般形式: Aαβ1| αβ2...| αβn 变为A α(β1| β2...| βn) 即有: A αA’ A’ β1| β2...| βn

  37. 例5.6 若文法G1的产生式为: (1)SaSb (2)SaS (3)Sε 对(1)(2)式: SaS(b| ε) 变为: SaSA Ab A ε S ε

  38. 例5.7 对文法G2的产生式: (1) Aad (2)ABc (3)BaA (4)BbB 产生式(2)右部以非终结符开始,可能导致公共因子。 用(3)(4)替换(2)得到: (1)Aad (2)AaAc (3)AbBc (4)BaA (5)BbB

  39. 提取(1)(2)左公因子 Aa(d|Ac) 引进A‘ AaA’ A’d|Ac 最后: AaA’ AbBc A’d A’Ac BaA BbB

  40. 例5.8 若有文法G3的产生式 • SaSd • SAc • AaS • Ab • 用(3)(4)替换(2) • (1)SaSd • (2)SaSc • (3)Sbc • (4)AaS • (5)Ab

  41. 引入A‘ (1)SaSA’ (2)Sbc (3)A’d|c (4)AaS (5)Ab

  42. 例5.9 若文法G4的产生式为: (1)SAp|Bq (2)AaAp|d (3)BaBq|e 用(2)(3)替换(1)得到 (1)SaApp|aBqq (2)Sdp|eq (3)AaAP|d (4)BaBq|e 对(1)提取左公因子得到: Sa(App|Bqq) 引入S‘最后: (1)SaS’ (2)Sdp|eq (3)S’App|Bqq (4)AaAp|d (5)BaBq|e

  43. 结论: (1)不一定每个文法的左公因子都能在有限的步骤内替换 成无左公因子的文法。 (2)一个文法提取了左公因子后,只解决了相同左部产生式 右部的FIRST集不相交问题,当改写后的文法不含空产生式, 且无左递归时,则改写后的文法是LL(1)文法,否则还需 用LL(1)文法的判断方式进行判断,才能确定是否为 LL(1)文法。

  44. 2、消除左递归 对于三个产生式: AAβ AB β BAα 会有A=+>A...,它称为文法中含有左递归,或间接左递归。

  45. 例5.10 文法G5 SSa Sb 其语法分析树如右: S S a S a ... S a

  46. 例5.11 文法G6: (1)AaB (2)ABb (3)BAc (4)Bd 对于输入串adbcbcbc# 其语法分析树为: A a B A c B b d

  47. 如果选用(3)式推导,则不能终止 A a B A c B b A c ...

  48. 消除左递归方法: (a)消除直接左递归,把直接左递归改写为右递归 对于SSa Sb 可改写为: SbS’ S’aS’|ε 一般情况下: 对于AAα1| Aα2|... Aαn|β1 |β2 |...βn 改写为: A β1 A‘| β2 A’|... βnA‘ A’ α1 A’| α2A’|... |αnA’|ε

  49. (b)消除间接左递归 先将间接左递归变为直接左递归,再进行删除。 例子:文法G6 (1)AaB (2)ABb (3)BAc (4)Bd 用(1)(2)代入(3)得到 (1)BaBc (2)BBbc (3)Bd 消除左递归后得到: B(aBc|d)B’ B’bcB’|ε 再把原产生式代入,得到: (1)AaB (2)ABb (3)B(aBc|d)B’ (4)B’bcB’|ε

  50. (c)消除文法中一切左递归的算法 (1)把文法的所有非终结符按某一顺序排序; 如A1,A2…An (2)从A1开始消除左部为A1的产生式的直接左递归,然后把左 部为A1的所有规则的右部逐个替换左部为A2右部以A1开始的 产生式中的A1,并消除左部为A2的产生式中的直接左递归。 (3)去掉无用产生式。

More Related