1、1,第6章 自底向上优先分析,又称 移进归约分析法,2,存在主要问题: 左递归问题 回溯问题,主要方法: 递归子程序法 LL分析法,自顶向下分析算法的基本思想为:,自底向上分析算法的基本思想为:,存在主要问题: 句柄的识别问题,主要方法: 算符优先分析法 LR分析法,3,6.1 概述,原理 在采用自左向右扫描,自底向上分析的前提下,该类分析方法是从输入符号串入手,通过反复查找当前句型的句柄(最左简单短语),并使用文法的产生式把句柄归约成相应的非终结符来一步步地进行分析的。最终把输入串归约成文法的开始符号,表明分析成功。,所以,任何自底向上分析方法的关键就是要找出当前句型的句柄(或是它的变形),
2、然后根据产生式判别将它归约成什么样的非终结符号。,4,两种理解从推导的角度,从输入符号出发,试图把它规约成识别符号。每一步都寻找特定的某个句型的短语(一般是简单短语)进行归约。在分析过程中,每次归约的都是最左边的简单短语(或最左素短语)。从语法树的角度,以输入符号为树的叶子结点,试图向根结点方向往上构造语法树。,5,规约示例,例6.1 S aABe A Abc | b B d,6,例6.1 S aABe A Abc | b B dabbcde,规约示例,7,例6.1 S aABe A Abc | b B dabbcdeaAbcde,规约示例,8,例6.1 S aABe A Abc | b B
3、dabbcdeaAbcdeaAde,规约示例,9,例6.1 S aABe A Abc | b B dabbcdeaAbcdeaAdeaABe,规约示例,10,例6.1 S aABe A Abc | b B dabbcdeaAbcdeaAdeaABeS,规约示例,11,例6.1 S aABe A Abc | b B dabbcdeaAbcdeaAdeaABeS 推导过程为输入串对应的最右推导的逆:S aABe aAde aAbcde abbcde,规约示例,12,【总结】自底向上分析的移进-规约是自顶向下最右推导的逆过程,而最右推导为规范推导,从而自左向右的规约过程也称为规范规约句柄 句型的句柄
4、是和某产生式右部匹配的子串,并且,把它归约成该产生式左部的非终结符,代表了最右推导过程的逆过程的一步 例6.1 S aABe A Abc | b B d S aABe aAde aAbcde abbcde,13,例6.2 E E + E | E E | (E ) | idE E E E E + E E E + E E + id3 E E + id3 E E + id3 E id2 + id3 E id2 + id3 id1 id2 + id3 id1 id2 + id3 可见句型id1 id2 + id3在规约过程中出现的句柄不唯一,注:如果文法二义,那么句柄可能不唯一,14,例6.3:文法,
5、SaAcBeA bA AbB d,构造输入串abbcde#分析过程,先设立一个符号栈,我们统一符号“#”作为待分析的符号串的左右分界符。 作为初始状态,先将符号串的分界符推进符号栈,作为栈底符号。,15,归约分析过程(移进归约):,SaAcBe A bA Ab B d,16,17,把上例倒过来写,则得到:S aAcBe aAcde aAbcde abbcde 显然这是一个最右推导。规范归约是关于是一个最右推导的逆过程最左归约 规范推导由规范推导推出的句型称为规范句型。,18,上述的每一步规约可以构造一颗语法树:,问题的提出:在构造语法树的过程中,何时规约,即如何确定当前句型的句柄?如何知道在栈
6、顶符号串中已经形成可归约串?,19,自底向上分析过程的实现,基本采用“移进归约”思想进行自下而上分析方法。使用一个栈来存放归约得到的符号。工作过程:把输入符号串按描述顺序一一地移进符号栈(一次移一个),检查栈中符号,当在栈顶的若干符号形成当前句型的句柄时,就根据规则进行规约,将句柄从符号栈中弹出,并将相应的非终结符号压入栈内(即规约的左部符号),,20,自底向上分析过程的实现(续),然后再检查栈内符号串是否形成新的句柄,若有就再进行规约,否则移进符号。分析一直进行到读到输入串的终止符为止。最后,若栈中仅含有终止符(#)和开始符号,则表示分析成功,否则失败。,21,自底向上分析过程的实现(续),
7、归约中的动作有4类移入:读入一个符号并把它移入栈。归约:当栈中的部分串已形成一个句柄(栈顶的符号序列)时,对句柄进行归约。接受:当栈中的符号仅有#和识别符号的时候,输入符号也到达结尾的时候,执行接受动作。报错:当识别程序觉察出错误的时候,表明输入符号串不是句子,进行错误处理。,22,自底向上分析过程的实现(续),特点:能力强,构造复杂,23,自下而上分析的关键问题: 如何确定可归约串?,两种自底向上的分析方法:简单优先分析法:寻找句柄算符优先分析法:寻找最左素短语,自底向上主要分析方法,24,基本思想 首先规定文法符号之间的优先关系和结合性质,然后再利用这种关系,通过比较两个相邻的符号之间的优
8、先顺序来确定句型的“句柄”并进行归约。,6.2 简单优先分析法,25,优先关系的表示 x y 表示X与Y的优先关系相等 xy 表示X的优先性大于Y x y 表示X的优先性小于Y,对任意两个文法符号X、Y按其在句型中可能会出现的相邻关系来确定优先关系。,26,确定优先关系的规则,(1)X Y 当且仅当G中存在产生式A XY(在语法树的同一层)(2)XY 当且仅当G中存在产生式A BY,且B X( X在 Y 的下一层),+,+,27,例6.4 有文法GS: SbAb A( B | a BAa )解:文法符号优先关系推导如下: (1) 求关系: 由SbAb , A( B, BAa ) b A, A
9、b, ( B, A a, a ),28,(2) 求关系: 由SbAb 且A (B 可得 b ( A a 可得 b a 由A( B 且B ( B 可得 ( ( B aa 可得 ( a B Aa ) 可得 (关系: 由SbAb,且A) 可得 ) b AB 可得 B b A a 可得 a b由BAa ),且A) 可得 ) a Aa 可得 a a AB 可得 B a,A(B(Aa) )A(BBAa,+,30,优先关系矩阵表示法:,所有符号#,矩阵中元素要么只有一种关系,要么为空!元素为空时表明该文法的任何句型中都不会出现该符号对的相邻关系。,31,简单优先文法,定义6.1: 如果某个文法满足:字符表中
10、的任意两个符号之间至多有一种优先关系成立。任何两个规则式的右部不相同。则称该文法为简单优先文法。第一点保证可以识别出句柄.第二点保证可以确定归约到哪个非终结符号。,32,如何确定句柄,原理:根据文法符号之间的优先关系确定句柄。在规范归约(最左归约)过程中,出现在栈顶的优先级相同的连续符号串就是句柄。,我们要通过两个相邻符号SiSi+1之间的关系来找到句柄:SiSi+1在句柄内:必然有规则USiSi+1(Si =Si+1 )Si在句柄内部,但是Si+1在句柄之后,必然有规则USi,且存在规范句型USi+1。( Si Si+1 )如果Si在句柄内,而Si-1在句柄外,那么必然存在规范句型Si-1U
11、,且 有USi。 (Si-1下一个待输入符号aj时为止,表明此时已经碰到了一个句柄的尾了;栈顶符号ai为句柄的尾,然后在栈里面向前(下)找,直到找到句柄的头ak,即找到ak-1 Cb ab:当且仅当文法G中存在形如 A Bb 的规则,且B= a 或者 B= aC。,+,+,+,+,44,算符优先文法,定义6.4:设有算符文法G,如果其任意两个终结符号之间,算符优先关系最多只有 ,三种关系的一种关系成立,那么该文法G称为算符优先文法(也称OPG文法)。,【注意】1.这三种优先关系和数学中的是不同的,它们是有序的,也就是若有ab成立,不一定有b-,但没有- b,b a存在;但不允许 ab,ab,4
12、8,构造优先关系矩阵的算法,FOR 每条规则Ux1x2xn DO FOR i:=1 TO n-1 DO BEGIN IF xi和xi+1均为终结符,THEN 置 xi xi+1 IF in-2,且xi和xi+2都为终结符号但 xi+1为非终结符号 THEN 置 xi xi+2 IF xi为终结符号xi+1为非终结符号 THEN FOR FIRSTVT(xi+1)中的每个b DO 置xixi+1 END,49,构造FIRSTVT(A)的算法,1. 根据定义直观计算FIRSTVT集,50,设一个栈S和一个二维布尔数组FU,b. FU, b=TRUE , 当且仅当 bFIRSTVT(U),按照规则1
13、)对数组元素赋初值,若FU,b为真则进栈 PROCEDURE INSERT(U,b) IF NOT FU,b THEN BEGIN FU,b:=TRUE 把(U,b)推进S栈 /* bFIRSTVT(U) */ END 将栈顶项弹出,设为(V,b),在用规则2)检查所有的产生式,若有形为AV的产生式,而FA,a的值是假,则令其变为真,且将(A,a)进栈,如此重复直到栈弹空为止,具体方法如下:,2.用形式化算法计算FIRSTVT集,51,BEGIN main FOR 每个非终结符号U和终结符b DO FU,b:=FALSE /*赋初值*/ FOR 每个形如Ub或UVb 的规则 DO INSERT
14、(U,b)WHILE S栈非空 DO BEIGN 把S栈的顶项弹出,记为 (V,b) /* bFIRSTVT(V)*/ FOR 每条形如UV的规则 DO INSTER(U,b); /* bFIRSTVT(U)*/ END OF WHILE END,上述算法的工作结果是得到一个二维的布尔数组F,从F 可以得到任何非终结符号U的FIRSTVT FIRSTVT(U)=b|FU,b=TRUE,52,例6.6,(0) E#E#(1) EE+T(2) ET(3) TT*F(4) TF(5) FPF (6) FP(7) P(E) (8) Pi,E#E# 为对原文法的扩充# 表示句子括号,53,构造LASTV
15、T(U)的算法,1.若有规则Ua或UaV,则aLASTVT(U),2.若有规则UV,且aLASTVT(V)则aLASTVT(U),54,例 6.6 文法GE:(1) EE+T(2) ET(3) TT*F(4) TF(5) FPF|P(6) P(E)(7) Pi,FIRSTVT(E)=+,*,(,iFIRSTVT(T)=*,(,iFIRSTVT(F)=,(,iFIRSTVT(P)=(,iLASTVT(E)=+,*,),iLASTVT(T)=*,),iLASTVT(F)=,),iLASTVT(P)=),i,优先关系例子,55,(1)EE+T (2) ET (3) TT*F (4) TF (5) F
16、PF|P (6) P(E) (7) Pi,3)关系找形如:ABb的产生式E+: 则 LASTVT(E) + T*: 则 LASTVT(T) * P: 则 LASTVT(P) E): 则 LASTVT(E) ),2) 关系找形如AaB的产生式(即在产生式中找终结符在前非终结符在后的相邻符号对)+T: 则 + FIRSTVT(T) *F: 则 * FIRSTVT(F)F: 则 FIRSTVT(F)(E: 则 ( FIRSTVT(E),1) 关系由(6),得 ( ),规定:对于开始符号E, 可假设扩充文法得:E#E# 因此有 # # 、 #E:则 # #,56,表达式文法GE的算符优先关表,57,算
17、符优先分析法的实现,如何找可规约串?算符优先分析技术的基本思想是通过比较相邻的终结符号之间的优先关系,确定句型的“句柄” (变形的句柄)。对于句型 N1a1Ni-1ai-1NiaiNjajNj+1aj+1NkakNk+1 满足关系ai-1aj+1 的最左子符号串Niai NjajNj+1就是要被归约的短语。,58,由于算符优先分析技术在分析的过程中,只考虑终结符之间的优先关系确定句柄,而与非终结符无关,因此,只需要知道把当前的句柄规约为某一非终结符即可,不必知道该非终结符的名字是什么,省去了单非终结符的规约。由于非终结符号是“不可见”的。因此,对于单规则,算符优先技术无法处理。定义6.5 素短
18、语是满足下面条件的短语:(1)至少包含一个终结符号。(2)该短语除它自身之外不再含任何更小的素短语最左素短语是指处于句型最左边的那个素短语。,注:与句柄的区别:至少包含一个终结符。(从而去掉了单非终结符的归约),59,素短语的例子,短语有T+T*F+i,T+T*F,T*F,T, i,句柄是T。,T不是素短语,因为其中不含终结符。 T+T*F+i,T+T*F不是素短语,因为其中包含了T*F。 素短语为T*F,i。 最左素短语为T*F,例6.7 给出句型T+T*F+i的短语、句柄和素短语,60,定理:句型(算符文法句型) N1a1Ni-1ai-1NiaiNjajNj+1aj+1NkakNk+1中满
19、足关系ai-1aj+1的最左子符号串Niai NjajNj+1就是句型的最左素短语。注:出现在ai左端和a j右端的非终结符号一定属于这个素短语,61,算符优先分析技术的实现,算符优先分析基本思想:设置一个符号栈S,用以寄存规约或待形成素短语的符号串;用一个工作单元b存放当前读入的终结符号判断S栈顶的终结符a和下一个输入符号b优先级ab:表明找到了素短语的尾,再往前找其头,并进行规约(规约时要检查是否有产生式右部与最左素短语形式相符)。无优先关系:出错规约成功:当读到句子结束符#时,S栈中只剩下#N,即只剩句子的最左括号#和一非终结符N,62,算符优先分析算法 输入:输入字符串w和优先关系表输
20、出:如果w是一个句子,则输出一个分析树;否则报告出错,算符优先分析方法技术实现模型,63,语义处理子程序,语义处理子程序需要根据栈里面的符号(和其它信息)分析是否是一个素短语。建议归约的时候,遵照以下法则:对于素短语 w = Ni-1TiNiTi+1TjNj+1归约到如下的产生式左部的非终结符号:该产生式中的右部符号串的符号个数与该素短语的符号个数相同,终结符对应Ti,Ti+1Tj,其符号名要与实际名一样,相应位置也一致。,64,文法GE:(1) EE+T (2) ET(3) TT*F (4) TF(5) FPF|P (6) P(E)(7) Pi,算符优先规约步骤示例,给出对输入串i+i#的规
21、约过程,规范规约过程,65,算符优先规约步骤示例,文法GE:(1) EE+T (2) ET(3) TT*F (4) TF(5) FPF|P (6) P(E)(7) Pi,给出对输入串i+i#的规约过程,算符优先规约过程,66,表达式文法GE的算符优先关表,67,两种规约对应的语法树分别如下所示:,图1 规范规约对应语法树,图2 算符优先规约对应的语法树,【总结】由于算符优先规约过程去掉了单非终结符之间的规约,所以得不到真正的语法树,而只是构造出语法树的框架,所以算符优先规约不是规范规约!,1、每次规约最左子串,确实是当前句型的最左素短语(语法树)2、没有完全按规则进行规约,因为素短语不一定是句柄,68,已知优先文法构造终结符优先关系矩阵,设置符号栈S,算法步骤如下:算法思想:第一个终结符(即#)入栈S。 把下一个输入符号读入SYM中,则比较当前栈顶第一个终结符Sj同SYM的优先关系,如果SjSYM。 从栈顶向下寻找最左素短语,直到Sk-1R,i=i+1;Si=R,N,Y,N,A,71,A,72,例:对符号串(i+i)*i的算符优先分析过程,步骤,栈,优先关系,Next,余下部分,动作,73,句型识别过程,74,识别得到的语法树,75,两种优先技术的比较,76,作业,