1 / 173

第五章

第五章. 语法分析 —— 自下而上分析. 5.1 自下而上分析基本问题. 所谓 自下而上分析法 就是从输入串开始,逐步进行 “ 归约 ” ,直至归约到文法的开始符号;或者说从语法树的末端开始,步步向上 “ 归约 ” ,直到根结。. 5.1.1 归约 实现思想 从输入符号串开始,从左到右进行扫描,将输入符号逐个移入一个栈中,边移入边分析,一旦栈顶符号串形成某个产生式的右部时,就用该产生式的左部非终结符代替,称为 归约 。重复这一过程,直到归约到栈中只剩下文法的开始符号时,则分析成功, 称为 “ 移进 - 归约 ” 方法 。. 例: G[S]: S→aAcBe

norton
Télécharger la présentation

第五章

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. 5.1 自下而上分析基本问题 所谓自下而上分析法就是从输入串开始,逐步进行“归约”,直至归约到文法的开始符号;或者说从语法树的末端开始,步步向上“归约”,直到根结。 5.1.1 归约 • 实现思想 从输入符号串开始,从左到右进行扫描,将输入符号逐个移入一个栈中,边移入边分析,一旦栈顶符号串形成某个产生式的右部时,就用该产生式的左部非终结符代替,称为归约。重复这一过程,直到归约到栈中只剩下文法的开始符号时,则分析成功, 称为“移进-归约”方法。

  3. 例:G[S]: S→aAcBe A→b A→Ab B→d 输入串为abbcde,判断是否归约到S? 设立一个符号栈,统一符号“#”作为待分析的符号串的左右分界符。 作为初始状态,先将符号串的分界符推进符号栈,作为栈底符号。

  4. 例:G[S]: S→aAcBe A→b A→Ab B→d 步骤 符号栈 输入符号串 动作 1 # abbcde# 准备.初始化 2 #a bbcde# 移进 3 #ab bcde# 移进 4 #aA bcde# 归约(A→b) 5 #aAb cde# 移进 6 #aA cde# 归约(A→Ab) 7 #aAc de# 移进 8 #aAcd e# 移进 9 #aAcB e# 归约(B→d) 10 #aAcBe # 移进 11 #S # 归约(S→aAcBe) 12 #S # 成功

  5. 步骤 符号栈 输入符号串 动作 1 # abbcde# 准备.初始化 2 #a bbcde# 移进 3 #ab bcde# 移进 4 #aA bcde# 归约(A→b) 5 #aAb cde# 移进 6 #aAA cde# 归约(A→b) 7 #aAAc de# 移进 8 #aAAcd e# 移进 9 #aAAcB e# 归约(B→d) 10 #aAAcBe # 移进 例:G[S]: S→aAcBe A→b A→Ab B→d 自下而上分析的中心问题是: 怎样判断栈顶的符号串的可归约性,以及如何归约?

  6. S A c e a B A b b d 例:G[S]: S→aAcBe A→b A→Ab B→d S 语法分析树 aAcBe aAcde aAbcde abbcde • 从语法树的角度看:从语法树的树叶开始,逐步向上归约构造分析树,直到形成根结。是最右推导的逆过程。

  7. 5.1.2 规范归约简述 掌握短语和直接短语和句柄三个重要概念 令G是一个文法,S是文法的开始符号,假定是文法G的一个句型,如果有: S*A 且 A +  则称是句型相对于非终结符A的短语。特别是,如果有 A   则称是句型相对于规则A 的直接短语,一个句型的最左直接短语称为该句型的句柄。 注意:短语的两个条件是:S*A 且 A + 

  8. EE+T  T+T  T*F+T  F*F+T  i*F+T  i*i+F  i*i+i 例:文法G: E  T|E+T T F|T*F F i | (E) (5.2) 的一个句型i1*i2+i3。 分析:∵E*F* i2+i3且Fi1,则称i1是句型i1*i2+i3的相对于非终结符F的短语,也是相对于规则F→i的直接短语。 又∵E * i1*F+i3且F i2,则i2是句型i1*i2+i3的相对于F的短语,也是相对于规则F→i的直接短语, 同样地,E*i1*i2+F且Fi3,则i3也是句型i1*i2+i3的相对于F的短语,也是相对于规则F→i的直接短语。

  9. ∵E * T*i2+i3,且T+i1,则i1是句型i1*i2+i3的相对于T的短语。 ∵E *i1*i2+T 且T +i3,则i3是句型i1*i2+i3的相对于T的短语。 ∵E *T+i3且T +i1*i2,则i1*i2是句型i1*i2+i3的相对于T的短语。 ∵E *E+i3且E +i1*i2,则i1*i2是句型i1*i2+i3的相对于E的短语。 ∵E *E 且E +i1*i2+i3,则i1*i2+i3是句型i1*i2+i3相对于E的短语。 即i1,i2,i3,i1*i2和i1*i2+i3都是句型i1*i2+i3的短语,而且i1,i2,i3均为直接短语,其中i1是最左直接短语,即句柄。

  10. 尽管有E +i2+i3,但是 i2+i3并不是i1*i2+i3句型的一个短语,因为不存在从E(文法开始符)到i1*E的推导。 注意:短语的两个条件是:S*A 且 A + 

  11. 例:设文法G: S(T)|a|ε TS|T,S 找出句型(a,(T),(T,S))所有的直接短语。 分析: ∵S+(S,(T),(T,S)),Sa ∴a是该句型相对于S的直接短语。 ∵S+(a,S,(T,S)),S(T) ∴(T)是该句型相对于S的直接短语。 ∵S+(a,(T),(T)),TT,S ∴T,S是该句型相对于T的直接短语。 其中a是该句型的句柄。

  12. 语法树的子树是由该树的某个结点(称为子树的根)及其所有分枝构成的部分树称为原树的一颗子树。语法树的子树是由该树的某个结点(称为子树的根)及其所有分枝构成的部分树称为原树的一颗子树。 • 语法树的简单子树是只有单层分枝的子树——这颗子树只有且必须有父子两代,没有第三代,由此,引出下述结论: • 每个句型(句子)都对应一颗语法树; • 每颗语法树的端末结点自左至右排列构成一个句型(句子); • 每颗子树的端末结自左至右排列构成一短语; • 每颗简单子树的端末结自左至右排列构成一直接短语; • 最左简单子树的端末结自左至右排列构成一句柄。 从句型的语法树上很容易找出句型的短语和直接短语。

  13. E E + T T F T * F i F i i E  T|E+T T F|T*F F i | (E) 例:i*i+i 的短语、直接短语和句柄 短语: i1,i2,i3,i1*i2和i1*i2+i3 直接短语:i1,i2,i3 句柄:i1

  14. S ( ) T T S , S S ( T ) , T ( T ) T S , a 例:句型= (a,(T),(T,S))的语法树如右图所示。短语是: ① (a,(T),(T,S)) ② a,(T),(T,S) ③ a,(T) ④ (T,S) ⑤ a ⑥ (T) ⑦ T,S

  15. S ( ) T T S , S S ( T ) , T ( T ) T S , a • 句型的语法树有3棵简单子树。由这3棵简单子树的叶子结点组成的符号串,则是句型的3个直接短语: ① a ② (T) ③ T,S • 句型的语法树的最左简单子树的叶子结点a便是句型的句柄。

  16. E E + T F E + T i T * F ET | E+T TF | T*F Fi | (E) 例:文法(5.2)的另一个句型E+T*F+i , 其短语、直接短语、句柄分别是? 解:EE+T  E+T+T  E+T*F+T  E+T*F+F E+T*F+i 短语有:i, T * F, E+T * F, E + T * F + i 直接短语有: i, T * F 句柄是:T * F

  17. 例:文法: E→E+T|T T→T*F|F F→id 句型:id1+id2*id3, 分析树: 短语: id1+id2*id3 (E1) id2*id3 (T1) id1 (E2, T2, F1) id2 (T3, F3) id3 (F2) 直接短语: id1 (F1) id2 (F3) id3 (F2) 句柄: id1 (F1) ①短语:以非终结符为根子树中所有从左到右排列的叶子; ②直接短语:只有父子关系的树中所有从左到右排列的叶子(树高为2); ③句柄:最左边父子关系树中所有从左到右排列的叶子(句柄是唯一的)。

  18. 问题:id1+id2是句型id1+id2*id3的短语吗? 答案:不是。 ①没有一个E的子树,它的全部叶子是id1+id2;或者 ②找不到某个E,使得 E*E*id3, E +id1+id2

  19. 假定是文法G的一个句子,称序列 n ,n-1 , n-2, …, 0 是的一个规范归约,如果此序列满足: (1) n = ; (2) 0为文法的开始符,即 0 =S; (3)对于任何的i, 0<i≤n, i-1是从i经把句柄替换为相应产生式的左部符号而得到的。 容易看到,规范归约是关于的一个最右推导的逆过程。因此规范归约也称最左归约。 在形式语言中,最右推导常被称为规范推导。由规范推导所得的句型称为规范句型。如果文法G是无二义的,那么规范推导的逆过程必是规范归约。 • 一个规范句型的句柄的右边只包含终结符号。

  20. S A c e a B A b b d 修剪语法树 Ab是句型aAbcde的句柄 d是句型aAcde的句柄 b是句型abbcde的句柄

  21. 5.1.3 符号栈的使用与语法树的表示 例:对于文法(5.2)输入串i1*i2+i3 的分析(规范归约)步骤可表示如下: 步骤 符号栈输入串动作 0 # i1*i2+i3# 预备 • #i1 *i2+i3# 移进i1 • #F *i2+i3# 归约,Fi • #T *i2+i3 # 归约,T F • #T* i2+i3# 移进 • #T*i2 +i3# 移进 • #T*F +i3# 归约,F i • #T +i3# 归约,T T*F • #E +i3# 归约,E T • #E+ i3# 移进 • #E+i3 # 移进 • #E+F # 归约, F i • #E+T # 归约, T F • #E # 归约,E E+T • #E # 接受

  22. 四类操作(action) • 移进(shift)-将当前输入符号移入栈顶top • 归约(reduce)-当“句柄”出现在栈顶(从栈中某处到栈顶top),则将“句柄”从栈顶弹出,并将相应产生式左部非终结符置入栈顶top。 • 接受(accept)-分析成功! • 报错(error)-出现语法错误,调错误恢复例程

  23. 分析技术的关键--句柄的识别 什么是句柄(handle)? 简单讲,句柄是一个产生式的右部;自下而上分析(移进-归约分析)过程,其实就是发现句柄并将句柄(产生式右部)替换成相应左部非终结符的过程。 如何寻找或确定一个句型的句柄,在后续章节介绍。

  24. 小结: 重要概念 自下而上分析法——移进-归约法 短语、直接短语、句柄 规范归约

  25. 5.2 算符优先分析 • 算符优先分析法的思想源于表达式的分析,即利用相邻终结符号之间的关系来寻找可归约串。 • 将句型中的终结符号当作“算符”,借助于算符之间的优先关系确定句柄。 • 显然,在一个符号串中,任意两个相邻终结符号a和b之间,只可能存在以下三种优先关系:(1) a, b优先性相同,记作a b。(2) a优先性高于b, 记作a b。(3) a优先性低于b ,记作a b。 如果以上三种关系中的任意两种都不会同时成立,则可以根据终结符号之间的关系进行语法分析。

  26. 5.2.1 算符优先文法及优先表的构造 一个文法,如果它的任何产生式的右部都不含两个相继(并列)的非终结符,即不含如下形式的产生式右部: …QR… 则称该文法为算符文法。 在后面的定义中,a、b代表任意终结符;P、Q、R代表任意非终结符;‘…’代表有终结符和非终结符组成的任意序列,包括空字。

  27. 假定G是一个不含--产生式的算符文法。对于任何一对终结符a、b,我们说:假定G是一个不含--产生式的算符文法。对于任何一对终结符a、b,我们说: (1) a b 当且仅当文法G中含有形如P …ab…或P …aQb…的产生式; (2) a b当且仅当G中含有形如P …aR…的产生式,而 R+b…或R +Qb…; (3) ab当且仅当G中含有形如P …Rb…的产生式,而R+…a或R +…aQ; 如果一个文法G中的任何终结符对(a, b )至多只满足下述三关系之一: a b, a b, a b 则称G是一个算符优先文法。 算符优先文法是无二义性的

  28. 以上三种关系也可由语法树来说明 注:δ为ε或Q

  29. a b 不一定 b a • 允许a b, b a; • 不允许 a b, a b, a b中任两个 同时存在。 • < • • • > > > 注意:3种关系与数学中的=、>、<不同。它们是有序的。 例如:E→E+E|E*E|(E)|i 不是算符优先文法。 +、* 的优先关系不唯一,所以该表达式的文法仅是算符文法而不是算符优先文法

  30. 通过检查G的每个产生式的每个候选式,可以找出满足a b的终结符对。 为了找出所有满足关系 和 的终结符对,需要对G的每个非终结符P 构造两个集合FIRSTVT(P)和LASTVT(P): FIRSTVT(P)={a | P+a…或P +Qa…,aVT而 Q VN } LASTVT(P)={a | P+…a或P +…aQ,aVT而 Q VN } 有了这两个集合后,就可以通过检查每个产生式的候选式确定满足关系 和 的所有终结符对。

  31. 例如:假定有个产生式的一个候选式为 …aP… 那末,对任何bFIRSTVT(P), 有a b。 假定有产生式的一个候选式为 …Pb… 那末,对任何aLASTVT(P), 有a b. 构造集合FIRSTVT(P)的算法。依据下面两条规则: (1)若有产生式Pa…或P Qa…,则aFIRSTVT(P) (2)若aFIRSTVT(Q),且有产生式P Q… 则aFIRSTVT(P) 说明:因为Qa…或QWa…,所以有PQ…a…或 PQ…Wa…

  32. 构造LASTVT(P)的算法 (1)若有产生式P … a或P  …aQ,则aLASTVT(P) (2)若aLASTVT(Q),且有产生式P  … Q 则aLASTVT(P)

  33. 例:文法G: Sa|^|(T) TS,T|S 计算各非终结符的FIRSTVT和LASTVT. 解:FIRSTVT(S)={a^(} Pa… LASTVT(S)={a^)} P … a FIRSTVT(T)={,a^(} PQa…规则2 LASTVT(T)={,a^)} P …aQ 规则2 构造集合FIRSTVT(P)的算法。依据下面两条规则: (1)若有产生式Pa…或P Qa…,则aFIRSTVT(P) (2)若aFIRSTVT(Q),且有产生式P Q…, 则aFIRSTVT(P) 构造LASTVT(P)的算法 (1)若有产生式P … a或P  …aQ,则aLASTVT(P) (2)若aLASTVT(Q),且有产生式P  … Q, 则aLASTVT(P)

  34. 说明:E′→#E#为对原文法的扩充,‘#’表示句子括号,说明:E′→#E#为对原文法的扩充,‘#’表示句子括号, 所描述的语言和扩充前完全相同。为了分析过程的确切,把'#'号也作为终结符对待。 例:表达式文法为:(0) E′→#E#(1) E→E+T(2) E→T(3) T→T*F(4) T→F(5) F→P↑F|P(6) P→(E)(7) P→i计算每个非终结符的FIRSTVT集合和LASTVT集合。   解:FIRSTVT(E′)={#}FIRSTVT(E)={+,*,↑,(,i}FIRSTVT(T)={*,↑,(,i}FIRSTVT(F)={↑,(,i}FIRSTVT(P)={(,i}LASTVT(E′)={#}LASTVT(E)={+,*,↑,),i}LASTVT(T)={*,↑,),i}LASTVT(F)={↑,),i}LASTVT(P)={),i}

  35. < • > P…ab… P…aQb… 在有了每个非终结符P 的FISTVT(P)和LASTVT(P)之后就能够构造文法G的优先表。其算法如下: FOR 每一条产生式PX1X2…Xn FOR i:=1 TO n-1 DO BEGIN IF Xi和 Xi+1均为终结符THEN 置 Xi Xi+1 IF i<=n-2且Xi和Xi+2都为终结符,而Xi+1为非终结符,则置Xi Xi+2 IF Xi为终结符而Xi+1为非终结符 THEN FOR FIRSTVT(Xi+1)中的每个a DO 置 Xi a IF Xi为非终结符而Xi+1为终结符THEN FOR LASTVT(Xi)中的每个a DO 置 a Xi+1 END P…aR.. R+b… R+Qb… P…Rb.. R+…a R+…aQ

  36. 构造优先关系表T的方法: • • < < • • > > a) 关系: 可直接查看产生式的右部,对如下形式的产生式A→…ab… , A→…aBb… 有T[a,b]= b) 关系: 对如下形式的产生式A→…aB… 中,对每一 b∈FIRSTVT(B), 有T[a,b]= c) 关系: 对如下形式的产生式A→…Bb… 中,对每一a∈LASTVT(B), 有T[a,b]=

  37. FIRSTVT(E′)={#}FIRSTVT(E)={+,*,↑,(,i}FIRSTVT(T)={*,↑,(,i}FIRSTVT(F)={↑,(,i}FIRSTVT(P)={(,i}LASTVT(E′)={#}LASTVT(E)={+,*,↑,),i}LASTVT(T)={*,↑,),i}LASTVT(F)={↑,),i}LASTVT(P)={),i}FIRSTVT(E′)={#}FIRSTVT(E)={+,*,↑,(,i}FIRSTVT(T)={*,↑,(,i}FIRSTVT(F)={↑,(,i}FIRSTVT(P)={(,i}LASTVT(E′)={#}LASTVT(E)={+,*,↑,),i}LASTVT(T)={*,↑,),i}LASTVT(F)={↑,),i}LASTVT(P)={),i} 例:表达式文法为:(0) E′→#E#(1) E→E+T(2) E→T(3) T→T*F(4) T→F(5) F→P↑F|P(6) P→(E)(7) P→i构造算符优先表   a) 关系由产生式(0) E′→#E# 和(6) P→(E)可得‘#’‘#’,‘(’')'成立。

  38. • • • • • < < < < < < • • • • • • > > > > > > c) 关系:对表达式文法中非终结符在前终结符在后的相邻符号对有:E# 则有:LASTVT(E) #E+ 则有:LASTVT(E) +T* 则有:LASTVT(T) *P↑ 则有:LASTVT(P) ↑E) 则有:LASTVT(E) ) b) 关系:对所给表达式文法 中终结符在前非终结符在后的 相邻符号对有: #E 则有:# FIRSTVT( E) +T 则有:+ FIRSTVT(T) *F 则有:* FIRSTVT(F) ↑F 则有:↑ FIRSTVT(F) (E 则有:( FIRSTVT(E) (0) E′→#E#(1) E→E+T(2) E→T(3) T→T*F(4) T→F(5) F→P↑F|P(6) P→(E)(7) P→i

  39. LASTVT(E) #LASTVT(E) +LASTVT(T) *LASTVT(P) ↑LASTVT(E) ) # FIRSTVT( E) + FIRSTVT(T) * FIRSTVT(F) ↑ FIRSTVT(F) ( FIRSTVT(E) ‘#’‘#’,‘(’')' • • • • • < < < < < • • • • • > > > > > 优先表 FIRSTVT(E’)={#}FIRSTVT(E)={+,*,↑,(,i}FIRSTVT(T)={*,↑,(,i}FIRSTVT(F)={↑,(,i}FIRSTVT(P)={(,i}LASTVT(E′)={#}LASTVT(E)={+,*,↑,),i}LASTVT(T)={*,↑,),i}LASTVT(F)={↑,),i}LASTVT(P)={),i}

  40. < • > FIRSTVT(S)={a^(} LASTVT(S)={a^)} FIRSTVT(T)={,a^(} 例:文法G: Sa|^|(T) TS,T|S 构造文法G的优先表。 LASTVT(T)={,a^)} 解:1) S (T) 得() 2) S (T) ,得(低于FIRSTVT(T)中的每一个 TS,T,得,低于FIRSTVT(T)中的每一个 3) S (T),得 LASTVT(T)中的每一个高于) TS,T,得LASTVT(S)中的每一个高于, 加入#S#

  41. 例:构造下面文法的算符优先表。 S if Eb then E else E E E+T|T T T*F|F F i Eb b 解:1)求各非终结符的首终结符集和尾终结符集。为了考虑语句的开始和结束符号“#”,对文法拓广,加一个产生式S’#S# FIRSTVT(S)={if} LASTVT(S)={else,+,*,i} FIRSTVT(E)={+,*,i} LASTVT(E)={+,*,i} FIRSTVT(T)={*,i} LASTVT(T)={*,i} FIRSTVT(F)={i} LASTVT(F)={i} FIRSTVT(Eb )={b} LASTVT(Eb)={b} 2)填写算符优先表

  42. 右左 if then else + * i b # if then else + * i b #

  43. 5.2.2 算符优先分析算法 • • < < • • > > 即:aj-1aj ... ai-1aiai+1 • • • 所谓素短语是指这样的一个短语,它至少含有一个终结符,并且除它自身外,不再含有更小的素短语。 所谓最左素短语,是指处于句型最左边的那个素短语。 把算符优先文法句型(括在两个#号之间)的一般形式写成: #N1a1N2a2…Nnan Nn+1# (5.4) 其中每个ai都是终结符,Ni是可有可无的非终结符。 一个算符优先文法G的任何句型(5.4)的最左素短语是满足如下条件的最左子串:Njaj…Nia iNi+1, a j-1 aj aj aj+1, … , a i-1 a i ai· a i+1

  44. E E + T 包含其他 素短语 F E + T T不包含终结符 T是句柄 i T T * F 例: 文法G[E] EE+T|T T  T*F|F F (E)|i 求句型T+T*F+i 的素短语 文法的语法树: 短语:T+T*F+i T+T*F T(最左) T*F i 只有T*F和i为素短语,其中T*F为最左素短语,而该句型句柄为T.

  45. 算符优先分析算法

  46. k=1;s[k]=‘#’; /* S为符号栈*/ repeat 将一个输入符号读入a中; IF S[k]VT THEN j=k ELSE j=k-1; While s[j] a { /*素短语归约可能做若干次*/ repeat q=s[j]; /*找素短语的头*/ if s[j-1]VT then j=j-1 else j=j-2 until s[j] Q; 将s[j+1]…s[k]归约为某个N;/*若找不到相应的产生式归约,则出错*/ k=j+1; s[k]=N } if s[j] a or s[j] a then { k=k+1;s[k]=a /*移进*/} else ERROR /*调出错处理程序*/ until a=‘#’ /*识别成功*/

  47. 例:根据下面文法及其算符优先表,按算符优先分析的算法分析语句if b then i else i#。 S if Eb then E else E E E+T|T T T*F|F F i Eb b 右左 if then else + * i b # if then else + * i b #

  48. 步骤 栈 关系* 输入串 动作 0 # if b then i else i # 1 #if b then i else i # 移进 2 # if b then i else i # 移进 3 #if N then i else i # 对b归约 4 #if N then i else i # 移进 5 #if N then i else i # 移进 6 #if N then N else i # 对i归约 7 #if N then N else i # 移进 8 #if N then N else i # 移进 9 #if N then N else N # 对i归约 10 #N # 归约 成功

  49. 例:文法G: Sa|^|(T) TS,T|S 给出句子((a,a),^)#的分析过程 文法G的优先表

More Related