编译原理之优先分析法华东交通大学软件学院万仲保第06章自底向上优先分析法自底向上优先分析概述简单优先分析法算符优先分析法自底向上分析方法概述自底向上分析方法,也称移进-归约分析法。实现思想是对输入符号串自左向右进行扫描,并将输入符逐个移入一个后进先出栈中,边移入边分析,一旦栈顶符号串形成某个句型的句柄时,就用该产生式的左部非终结符代替相应右部的文法符号串,这称为一步归约。重复这一过程直到归约到栈中只剩文法的开始符号时则为分析成功,也就确认输入串是文法的句子。示例abbcde步骤符号栈输入符号串动作1)#abbcde#移进2)#abbcde#移进A3)#abbcde#归约(A→b)4)#aAbcde#移进A5)#aAbcde#归约(A→Ab)6)#aAcde#移进7)#aAcde#移进B8)#aAcde#归约(B→d)9)#aAcBe#移进11)#S#接受S10)#aAcBe#归约(S→aAcBe)分析符号串abbcde是否G[S]的句子对输入串abbcde#的移进-规约分析过程SaAcBeaAcdeaAbcdeabbcde最右推导:示例文法G[S]:(1)S→aAcBe(2)A→b(3)A→Ab(4)B→d简单优先分析法按照文法符号(包括终结符和非终结符)的优先关系确定句柄。定义优先关系简单优先文法优先关系矩阵:表示文法符号之间关系的矩阵。算法示例优先关系X≖Y:表示X、Y的优先关系相同,当且仅当文法G中存在产生式A→...XY…;X⋖Y:表示X的优先性比Y的要低,当且仅当文法G中存在产生式A→...XB...,且BY...X⋗Y:表示X的优先性比Y的要高,当且仅当文法G中存在产生式A→...BD...,且B...X,DY*优先关系的定义简单优先文法的定义满足以下条件的文法是简单优先文法:(1)在文法符号集V中,任意两个符号之间最多只有一种优先关系成立;(2)在文法中任意两个产生式没有相同的右部。简单优先分析法——算法根据已知优先文法构造相应优先关系矩阵,并将文法的产生式保存,设置符号栈S,算法步骤如下:1.将输入符号串a1a2a3...an#依次逐个存入符号栈S中,直到遇到栈顶符号ai的优先性.下一个待输入符号aj时为止。2.栈顶当前符号ai为句柄尾,由此向左在栈中找句柄的头符号ak,即找到ak-1⋖ak为止。3.由句柄ak...ai在文法的产生式中查找右部为ak...ai的产生式,若找到则用相应左部代替句柄,若找不到则为出错,这时可断定输入串不是该文法的句子。4.重复上述三步,直到归约完输入符号串,栈中只剩文法的开始符号为止。简单优先文法分析示例文法G[S]:(1)S→bAb(2)A→(B|a(3)B→Aa)1、确定文法符号之间的关系2、求出文法的简单优先关系矩阵3、对输入串进行分析(输入串b(aa)b#)确定文法符号之间的关系1.求≖关系:•由(1):b≖AA≖b•由(2):(≖B•由(3):A≖aa≖)2.求⋖关系:•由(1)(2):b⋖(b⋖a•由(2)(3):(⋖A(⋖((⋖a3.求⋗关系:•由(1):B⋗ba⋗b)⋗b•由(3):B⋗aa⋗a)⋗a求出文法的简单优先关系矩阵SbA(Ba)#S·b·=···A·=·=(···=·B··a···=)··#···=“#”用来表示语句括号,其优先关系低于所有与其有相邻关系的文法符号。对输入串进行分析(输入串b(aa)b#)步骤符号栈输入符号串动作1)#b(aa)b##⋖b,移进2)#b(aa)b#b⋖(,移进3)#b(aa)b#(⋖a,移进4)#b(aa)b#a.a,归约A→a5)#b(Aa)b#A.=a,移进6)#b(Aa)b#a.=),移进7)#b(Aa)b#).b,归约B→Aa)8)#b(Bb#B.b,归约A→(B9)#bAb#A.=b,移进10)#bAb#b.#,归约S→bAb11)#S#接受SbA(Ba)#S·b·=···A·=·=(···=·B··a···=)··#···=文法G[S]:(1)S→bAb(2)A→(B|a(3)B→Aa)算符优先分析法某些文法具有“算符”特性表达式运算符(优先级、结合性);人为地规定其算符的优先顺序,即给出优先级别和同一级别的结合性;只考虑算符之间的优先关系来确定句柄。定义算符文法算符优先关系算法优先文法最左素短语算符优先关系表的构造算符优先分析法概述算符优先文法的性质算符优先分析算法优先函数算符优先分析法的局限性算符文法的定义如果不含空产生式的上下文无关文法G中没有形如U…BC…的产生式,其中B,C∈VN,则称G为算符文法(OperaterGrammar,OG)。性质1:在算符文法中任何句型都不包含两个相邻的非终结符。(归纳法)2:如Vx或xV出现在算符文法的句型中,其中V∈VN,x∈VT,则中任何含x的短语必含有V。(反证法)用归纳法设是句型,即S⇒*S=ω0⇒ω1⇒...⇒ωn-1⇒ωn=推导长度为n,归纳起点n=1时,S=ω0⇒ω1=,即S⇒,必存在产生式S→,而由算符文法的定义,文法的产生式中无相邻的非终结符,显然满足性质1。假设n>1,ωn-1满足性质1。若ωn-1=A,A为非终结符。由假设知α的尾符号和δ的首符号都不可能是非终结符,否则与假设矛盾。又若A→是文法的产生式,则有ωn-1⇒ωn==而A→是文法的原产生式,不含两个相邻的非终结符,所以也不含两个相邻的非终结符。满足性质1。证毕。反证法因为由算符文法的性质1知可有:S⇒*=bAβ若存在B⇒*b,这时b和A不同时归约,则必有S⇒*BAβ,这样在句型BAβ中存在相邻的非终结符B和A,所以与性质1矛盾,证毕。注意:含b的短语必含A,含A的短语不一定含b。算符优先关系的定义设G是不含产生式的文法,a、b是任意两个终结符,A、B、C是非终结符,算符优先关系的定义如下:a≖b当且仅当G中有形如A…ab…或A…aBb…的产生式。a⋖b当且仅当G中有形如A…aB…的产生式,且B⇒+b…或B⇒+Cb…a⋗b当且仅当G中有形如A…Bb…的产生式,且B⇒+…a或B⇒…aC注意:算符优先关系中不存在递推关系,即a≖bb≖c⇏a≖c或a⋖bb⋖c⇏a⋖c或a⋗bb⋗c⇏a⋗c优先关系的语法树表示方式优先关系的语法树表示方式算符优先文法的定义设G是不含产生式的算符文法,如果对任意两个终结符对a、b之间至多只有一种算符优先关系存在,则称G为算符优先文法。结论算符优先文法是无二义的。算符优先关系表的构造集合的定义:FIRSTVT(B)={b|B⇒+b…或B⇒+Cb...}对于非终结符B,其往下推导所可能出现的首个算符(终结符)LASTVT(B)={a|B⇒+…a或B⇒+...aC}对于非终结符B,其往下推导所可能出现的最后一个算符(终结符)构造方式:由定义直接构造由关系图法构造构造算法由定义计算算符优先关系直接计算算法计算关系图计算直接计算算符优先关系‘≖‘关系直接看产生式的右部,若出现了A→…ab…或A→…aBb,则a≖b’⋖‘关系求出每个非终结符B的FIRSTVT(B)若A→…aB…,则b∈FIRSTVT(B),a⋖b’⋗’关系求出每个非终结符B的LASTVT(B)若A→…Bb…,则a∈LASTVT(B),a⋗b示例直接计算示例文法G[E]:(0)E’→#E#(1)E→E+T(2)E→T(3)T→T*F(4)T→F(5)F→PF|P(6)P→(E)(7)P→iFIRSTVT(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}1)≖关系由产生式(0)和(6),得#≖#,(≖)3)⋗关系找形如:A→…Bb…的产生式E#,则LASTVT(E)⋗#E+,则LASTVT(E)⋗+T*,则LASTVT(T)⋗*P,则LASTVT(P)⋗E),则LASTVT(E))2)⋖关系找形如:A→…aB…的产生式#E:则#⋖FIRSTVT(E)+T:则+⋖FIRSTVT(T)*F:则*⋖FIRSTVT(F)F:则⋖FIRSTVT(F)(E:则(⋖FIRSTVT(E)+*↑i()#+⋗⋖⋖⋖⋖⋗⋗*⋗⋗⋖⋖⋖⋗⋗↑⋗⋗⋖⋖⋖⋗⋗i⋗⋗⋗⋗⋗(⋖⋖⋖⋖⋖≖)⋗⋗⋗⋗⋗#⋖⋖⋖⋖⋖≖算法计算算符优先关系算法规则:1、若有产生式Aa…或ABa…,则aFIRSTVT(A),其中A、B为非终结符,a为终结符;2、若aFIRSTVT(B)且有产生式ABb…,则有aFIRSTVT(A)。算法:文本描述按规则1对每个数组元素F[A,a]赋初值,并对数组元素F[A,a]初值为真的符号对(A.a)都放入栈中,然后对栈做如下运算。当栈不空时,就将栈顶项弹出,并记为(B,a),再用规则2,若F[A,a]为假,则使其变为真,且将(A,a)推进栈,如此重复直到栈折空为止。程序描述示例程序描述将置为真的操作:PROCEDUREINSERT(A.a);IFNOTF[A,a]THENBEGINF[A.a]:=TRUNPUSH(A.a)0NT0STRACKEND主程序:BEGIN(MAIN)FOR每一个非终结符A和终结符a,DOF[A,a]:=FALSE;FOR每个形如Aa··或ABa…的产生式DOINSERT(A,a)WHILESTACK非空DOBEGIN把STACK的顶项记为(B,a)托出去FOR每个形如AB…的产生式DoINSERT(A,a)ENDEND算法计算示例文法G[E]:(0)E’→#E#(1)E→E+T(2)E→T(3)T→T*F(4)T→F(5)F→PF|P(6)P→(E)(7)P→i首次扫描STRACK的初值:(6)(P,i)(5)(P,()(4)(F,)(3)(T,*)(2)(E,+)(1)(E’,#)栈顶(6)的改变:FP(F,i)TF(T,i)ET(E,i)由于无右部以E开始的产生式,所以(E,i)弹出后无进栈项,此时当前的栈顶为(P,()。栈顶(5)的改变:FP(F,()TF(T,()ET(E,()(E,()弹出后无进栈项,此时当前的栈顶为(F,)。栈顶(4)的改变:TF(T,)ET(E,)(E,)弹出后无进栈项,此时当前的栈顶为(T,*)。栈顶(3)的改变:ET(E,*)以下逐次弹出栈顶元素后,都再无进栈项,直至栈空。+*↑i()#E’1E11111T111F111P11FIRSTVT(E’)={#}FIRSTVT(E)={+,*,,(,i}FIRSTVT(T)={*,,(,i}FIRSTVT(F)={,(,i}FIRSTVT(P)={(,i}关系图计算算符优先关系关系图的构造方法图中的结点为非终结符的FIRSTVT(A)和终结符;对每一个形如Aa…或ABa…的产生式,则构造由FIRSTVT(A)结点到终结符结点(a)用箭弧连接的图形;对每一个形如AB…的产生式,则对应图中由FIRSTVT(A)结点到FIRSTVT(B)结点用箭弧连接;对每一非终结符的FIRSTVT(A)经箭弧有路径能到达的终结符结点(a),则有aFIRSTVT(A)。示例关系图计算示例FIRSTVT(E’)FIRSTVT(E)FIRSTVT(T)FIRSTVT(F)FIRSTVT(P)#+*()文法G[E]:(0)E’→#E#(1)E→E+T(2)E→T(3)T→T*F(4)T→F(5)F→PF|P(6)P→(E)