1、2 自底向上分析,算符优先分析法 LR(0)分析法 SLR(1)分析法 LR(1)分析法 LALR(1)分析法,语法分析方法,把一个输入符号串逐步归约到文法的开始符号。实现这种方法的大致过程是,用一个栈,把输入符号一个一个地移进到栈里,当栈顶形成某个产生式的右部( 句柄)时,把栈顶的这一部分替换成(归约为)它的左部符号。直到移进所有的输入终结符号串,若栈内是开始符号,则符合语法,否则不是文法的句子,这种分析称作“移进归约”分析。,4.4 自底向上分析的思想,例 GS,其产生式如下: SaABe Ab AAbc Bd 输入串 abbcde 是否为文法的句子?,abbcde,aAbcde,aAde
2、,aABe,S,4.4.1 规范归约,SaABe aAde aAbcde abbcde,由最右推导得到的句型称为右句型,例 GS,其产生式如下: SaABe Ab AAbc Bd,这一归约过程是最右推导的逆过程,称为规范归约或最左归约。,最右推导也称为规范推导,从左至右扫描输入符号串 ,自然在被归约的句型中找最左边的某个产生式的右部进行归约。,注意:每一步都是把句柄替换为相应产生式的左部符号,为什么归约时采用最左归约?,定义假定是文法G的一个句子。称右句型序列 n , n-1, 1, 0 是 的一个规范归约,如果序列满足 1. n= , 0=S; 2.i(0 i n), i-1 是把i中的句柄
3、替换为相应产生式的左部符号得到的。,abbcde aAbcde aAde aABe S,如果文法G是无二义的,那么,规范推导(最右推导)的逆过程必是规范归约(最左归约)。,对于规范句型来说,句柄的后面不会出现非终结符号(句柄的后面只能出现终结符号)。,abbcde,aAbcde,aAde,aABe,S,二义性文法规范归约过程中右句型的句柄可能不唯一。例如,文法 GE:GE: EE+E|E-E|E*E|E/E|EE|(E)|-E|id句子id + id*id有两个不同的最右推导 :EE+E EE*E E + E*E E *id E + E*id E+E*id E + id*id E+id*id
4、id + id*id id+id*id句型EE*id中 ,句柄不唯一 。,4.4.2 “移进- 归约”分析法的栈实现 “移进一归约”分析器使用一个栈和一个存放输入符号串w的缓冲器。分析器的初始状态为:,工作过程:自左至右把串w 的符号一一移进栈里,一旦栈顶形成句柄时,就进行归约。这种归约可能持续多次,直至栈顶不再呈现句柄为止。然后,继续向栈里移进符号,重复这个过程,直至最终形成如下格局:,#,abbcde#,移进,#a,bbcde#,移进,bcde#,bcde#,移进,cde#,cde#,移进,de#,移进,e#,e#,移进,#,#S,#,接受,“移进-归约”分析对符号栈有四类操作:移进、归约
5、、接受和出错处理。,Gs: SaAcBe A bAb B d,规范归约的“最左”特征使得在移进-归约方法中,可归约串处于符号栈的栈顶。,分析过程的每一步骤,栈里的文法符号串加上剩余输入符号串恰好是一个规范句型。,分析过程的每一步骤,栈里的文法符号串加上剩余输入符号串恰好是一个规范句型。而且栈里的文法符号串正好是这个句型的一个活前缀。如在上表的前三步中可以看到,a及ab都是符号串abbcde的活前缀。,“移进-归约”分析可以识别规范句型的活前缀。,规范归约的中心问题是:如何寻找或确定一 个句型的句柄 。,各种自底向上分析方法的共同点是,都采用“移进- 归约”分析思想,不同点是确定可归约串的方法不
6、同。,算符文法的定义算符优先分析法的基本思想利用算符优先关系寻找右句型的可归约串算符优先关系表的构造优先函数,4.5 算符优先分析法与算符优先分析器,这是一种经典的自底向上分析法,简单直观,并被广泛使 用,开始主要是对表达式的分析,现在已不限于此。可以 用于一大类上下无关的文法.称为算符优先分析是因为这种 方法是仿效算术式的四则运算而建立起来的.,EEAE|(E)|-E|id A|*|/| 不是算符文法(因右部EAE具有相邻的非终结符号)。,GE: EEE|E-E|E*E|E/E|EE|(E)|-E|id 是算符文法。,可按传统的习惯规定优先级从高到低为:乘幂运算符,乘、除运算符,加、减运算符
7、;同级运算符服从左结合原则;有括号时,先括号内后括号外。从而可以消除最右推导的不唯一 ,可以唯一的确定可归约串.,文法的句子ididid*(idid)的归约过程为: (1)ididid* (idid ) (2) Eidid*(idid ) (3) EEid*(idid ) (4) Eid*(idid ) (5) EE*(idid) (6) EE*(Eid) (7) EE*(EE) (8) EE*(E) (9) EE* E (10) EE (11) E,GE: EEE|E-E|E*E |E/E| (E)|-E|id,归约过程中起决定作用的是相邻两个终结符号之间的优先关系。一旦确定了这种优先关系,
8、就可以借助这种关系去寻找可归约串并进行归约。算符优先分析法的本质就是借助优先关系来寻找归约条件和决定归约原则。,上述归约过程中的依据是什么?,注意:算术关系“”与优先关系具有不同的性质。例如,a a,例如:+ ( 而( +终结符号之间也可能不存在优先关系) (,一个文法的终结符之间的优先关系可用一个矩阵来表示(称为优先关系表)。 优先关系矩阵的最左边一列,代表所比较的终结符号对中左边的一个,是位于符号栈内的字符;最上一行代表所比较的终结符号对中右边的一个。矩阵元素代表两个终结符号之间的优先关系。其中最左边一列#表示栈底符,最上面一行的表示输入串的终止界符。,#作为每一个右句型符号串的左右分界符
9、,算符文法右句型的形式为:# 0a11a22ann # 并规定,ai, # # 。,移去上述右句型中的非终结符号,在每一对相邻终结符号之间放置优先关系,在句型中加入优先关系,例如:id+id*id# id + id * id # # + * #,GE: EEE|E-E|E*E|E/E|EE|(E)|-E|id,# + * #,# * #,# id + id * id #,GE: EEE|E-E|E*E|E/E|EE|(E)|-E|id,# E + id * id #,# E + E * id #,# #,# E + E * E #,# #,# E + E #,# #,# E #,# #,栈 关
10、系 输入 动作,# id+id*id# 移进,# id +id*id# 归约,# E +id*id# 移进,# E+ id*id# 移进,# E+id *id# 归约,# E+E *id# 移进,# E+E * id# 移进,# E+E * id # 归约,# E+E * E # 归约,# E+E # 归约,# E # 接受,算法4.4 算符优先分析法 if (ab) or (ab) /* 移进* / 把b推入栈中;使ip前进到下一个符号; if ab /* 归约* / repeat 从栈中弹出符号 until 栈顶终结符号最近弹出的终结符号else error,算法中,每一个归约串中至少包含
11、一个终结 符号,用到了一个重要的概念和结论。定义4.5 设G是一个算符文法,是句型关于A的短语(即有S A且A )且至少含有一个终结符号,并且除自身之外不再含有任何更小的 带有终结符号的短语,则称是句型关于A的素短语。所谓最左素短语是指处于句型最左边的那个素短语。,*,+,GE: (算符文法) EET | T TT*F | F F(E) | a,T + T*F + a,句型 T + T*F + a 的短语:,a和T*F是素短语 T*F是最左素短语,GE: (算符文法) EET | T TT*F | F F(E) | a,T + T*F + a,E,E,+,E,*,E,E,# id + id *
12、 id #,# E + id * id #,# E + E * id #,# E + E * E #,# E + E #,# E #,GE: EEE|E-E|E*E|E/E|EE|(E)|-E|id,算符优先分析法确定的可归约串是最左素短语对某些算符文法来说也是句柄,最左素短语,id,id,id,E*E,E+E,4.5.2 算符优先关系表的构造一、直观方法:(代数规则)(1)id是最基本的运算量(2)利用优先级,如先算乘除,再算加减,同级运算根据先后次序(3)+,-是左结合。二、形式方法,表4.9 优先关系表,(1)算符优先文法(OPG),二、形式方法,优先关系的定义,若G是一OG文法,a,b
13、Vt , U,V,WVna,b之间优先关系分别有以下三种情况:,1) a=b if 文法中有形如 U ab或U aVb的规则。 2) ab if 文法中有形如 U Wb 的规则, 其中W a或W aV 。,+,+,.,+,+,.,.,算符优先文法(OPG)的定义,设有一OG文法,如果在任意两个终结符之间, 至多只有上述关系中的一种,则称该文法为算符 优先文法(OPG)。,(2)构造优先关系矩阵,求 “ = ” 检查每一条规则,若有U ab或U aVb, 则 a=b,.,.,.,.,若文法有规则W .aU. ,对任何b, bFIRSTVT(U)则有:a b,.,若文法有规则W .Ub. ,对任何
14、a, aLASTVT(U)则有:a b,.,.,.,构造FIRSTVT(U)的算法,1)若有规则U b或U Vb(说明存在Ub或UVb)则bFIRSTVT(U),+,+,2)若有规则U V且bFIRSTVT(V), 则bFIRSTVT(U)说明:因为Vb或VWb,所以有UVb或UV Wb,+,+,+,+,设有下列算符优先文法G:A a | (R)T A , T | AR T 求如下FIRSTVT 集合。,设有下列文法G:S a | (T) | bTT T , S | S,FIRSTVT(S)=?,FIRSTVT(T)=?,构造LASTVT(U)的算法,1.若有规则U a或U aV,则aLAST
15、VT(U),2.若有规则U V,且aLASTVT(V)则aLASTVT(U),设有下列算符优先文法G:A a | (R)T A , T | AR T,设有下列文法G:S a | (T) | bTT T , S | S求,LASTVT(S)=?,LASTVT(T)=?,FIRSTVT(A)= a ( ,FIRSTVT(T)= , a ( ,FIRSTVT(R)= , a ( ,LASTVT(A)= a ) ,LASTVT(T)= , a ) ,LASTVT(R)= , a ) ,.,设有下列文法GA:A a | (R)T A , T | AR T 求出该文法的优先关系表。,FIRSTVT(A)=
16、 a ( ,LASTVT(A)= a ) ,.,# 怎么办?,4.5.3 优先函数 为了节约存储空间和便于执行比较运算 ,用两个优先函数f(栈内优先函数)和g(栈外优先函数),它们是从终结符号映射到整数的函数。对于终结符号a和b选择f和g,使之满足:1当a b时, f(a) g(b)。于是a和b之间的优先关系可以由比较f(a) 与g(b)的大小来决定。,优先关系表,对应的优先函数表:,1) 构造优先函数的算法不是唯一的。 2) 如存在一组优先函数,那就存在无穷组优先函数。 3) 错误检测能力降低,例如f(id) g(id) id id 4) 不一定每一个优先关系表都能找到对应的优先函数,#,f
17、(a)=g(a) f(a)g(b) f(b)=g(a) f(b)=g(b),f(a) = g(a) = f(b) = g(b),与f(a) g(b)矛盾,因此优先函数不存在,算法4.5 从优先关系表构造优先函数 方法:1.aVT#,建立两个符号fa和ga;2. 若a = b, 则把fa和gb分在一组;3. a,b VT,若a b,则从fa至gb画一条弧;若a b,则从gb至fa画一条弧;4 .若图中无环路,则存在优先函数,f(a)和g(b)分别等于从fa 和gb出发的最长路径(每一条箭弧长度为1)。,.,gid,fid,f*,g*,g+,f+,f#,g#,无环路,f( g),fa,ga,g(,f),f,,g,,f#,g#,算符优先分析器在以下两种情况下发现语法错误:如果栈顶上的终结符号和当前输入符号之间没有优先关系成立。2. 发现没有一个产生式的右部与当前可归约串相同,