收藏 分享(赏)

第5章 自底向上的句法分析.ppt

上传人:fmgc7290 文档编号:7877951 上传时间:2019-05-28 格式:PPT 页数:128 大小:1.04MB
下载 相关 举报
第5章 自底向上的句法分析.ppt_第1页
第1页 / 共128页
第5章 自底向上的句法分析.ppt_第2页
第2页 / 共128页
第5章 自底向上的句法分析.ppt_第3页
第3页 / 共128页
第5章 自底向上的句法分析.ppt_第4页
第4页 / 共128页
第5章 自底向上的句法分析.ppt_第5页
第5页 / 共128页
点击查看更多>>
资源描述

1、5 自底向上的分析方法,思想:从输入串出发,反复利用产生式进行归约,如果最后能得到文法的开始符号,则输入串是句子,否则输入串有语法错误。 核心:寻找句型中的“可归约串”进行归约,用不同的方法寻找可归约串,就可获得不同的分析方法。,移进-归约分析器思想:对输入符号串自左向右进行扫描,并将输入符号逐个移入一个后进先出栈中,边移入边分析,一旦栈顶符号串形成某个句型的可归约串时,(对应某产生式的右部),就用该产生式的左部非终结符代替该栈顶符号串,完成一次归约。重复这一过程直到归约到栈中只剩文法的开始符号时则为分析成功,也就确认输入串是文法的句子。,动作移进:把下一个输入符号压栈成为栈顶。归约:语法分析

2、器知道句柄的右端已在栈顶。它必须在栈中确定句柄的左端,并选择正确的非终结符替代句柄。接受:语法分析器宣告分析成功。出错:语法分析器发现了一个错误,并调用错误恢复程序进行错误处理。,例如,文法GS为:SaAbBAcAcBd试对输入串accbd进行分析,检查该符号串是否是GS的一个句子。,对输入串accbd自底向上的分析过程,SaAbB AcAc Bd,自底向上构造分析树的过程,在这里每一步的“可归约串”是句柄。句柄的“最左”特征,这一点对于“移进归约”来说很重要,因为句柄的“最左”性和分析栈的栈顶两者是相关的。对于规范句型来说,句柄的后面不会出现非终结符。基于这一点,我们可用句柄来刻画“移进归约

3、”过程的“可归约串”。因此,规范归约的实质是,在移进过程中,当发现栈顶呈现句柄时就用相应产生式的左部符号进行替换(即归约)。,句柄一个字符串的“句柄”是和一个产生式右部匹配的子串,而且把它归约到该产生式左部的非终结符代表了最右推导逆过程的一步。匹配某个产生式A右部的最左输入子串不一定是句柄,因为用这个产生式归约产生的串不能归约成开始符号。如果文法是二义性的,则句柄不一定唯一,因为可能有不止一个最右推导。,句柄裁剪句柄代表了由一个内节点和其所有子节点组成的最左简单子树。在句型中,把归约到一个非终结符A可以想象成“裁剪句柄”,即把语法树中内节点A的所有子孙节点删除。之后,A成为新的叶节点。通过“裁

4、剪句柄”可以得到最右推导的逆过程。,如果w是文法的一个句子,有: S=012n-1n=w为了构造推导的逆过程,关键是在i中寻找句柄i,并用产生式Aii的右部代替得到i-1 i。,修剪语法树实现归约,优先分析法,简单优先分析法 对一个文法按一定原则求出该文法所有符号(终结符和非终结符)之间的优先关系,按照这种关系确定归约过程中的句柄,它的归约实际上是一种规范归约。 优先关系 X Y 文法G中存在产生式A.XY. X Y 文法G中存在产生式A.BD., 且B+.X,D*Y.,例如,文法GS: (1) S bAb (2) A (B|a (3) B Aa) 关系:b A, A b, ( B, A a,

5、 a ) 关系:由S bAb,且A+ (B, A+a, A+), 有B b, a b, ) b;由B Aa),且A+ (B, A+a, A+), 有B a, a a, ) a。,简单优先关系矩阵,(1) S bAb (2) A (B | a (3) B Aa),简单优先文法的定义 满足以下条件的文法是简单优先文法 (1)在文法符号集V中,任意两个符号之间最多只有一种优先关系成立。 (2)在文法中任意两个产生式没有相同的右部。 (3)不含空产生式。,简单优先分析法 (1)将输入符号串a1a2an#依次逐个放入符号栈中,直到栈顶符号ai的优先性下一个待输入符号ai+1为止。 (2)以当前栈顶符号a

6、i为句柄尾,向下在栈中找句柄的头符号ak,即找到ak-1ak为止。 (3)在文法中查找右部为句柄akai的产生式,若找到则用相应左部代替句柄,若找不到则为出错,输入串不是文法的句子。 (4)重复(1)、(2)、(3)步骤直到规约完输入符号串,栈中只剩文法的开始符号为止。,步骤,符号栈,输入符号串,动作,1) # b(aa)b# #b,移进,2) #b (aa)b# b(,移进,3) #b( aa)b# (a,移进,4) #b(a a)b# aa,归约Aa,5) #b(A a)b# A=a,移进,6) #b(Aa )b# a=),移进,7) #b(Aa) b# )b,归约BAa),8) #b(B

7、 b# Bb,归约A(B,9) #bA b# A=b,移进,10) #bAb # b#,归约SbAb,11) #S # 接受,对输入串b(aa)#的简单优先分析过程,(1) S bAb (2) A (B | a (3) B Aa),算符优先分析法 只规定算符(终结符)之间的优先关系。找到最左素短语就归约,不是规范归约。 某些文法具有“算符”特性 表达式运算符(优先级、结合性) 人为地规定其算符的优先顺序,即给出优先级别和同一级别的结合性 只考虑算符之间的优先关系来确定最左素短语。 例 文法 GE:EE+E|E-E|E*E|E/E|EE|(E)|i,运算符的优先级和结合性满足通常的算术运算约定。

8、 (0)i的优先级最高 (1)优先级次于i,右结合 (2)*和/优先级次之,左结合 (3)+和-优先级最低,左结合 (4)括号(,)的优先级大于括号外的运算符,小于括号内的运算符,内括号的优先性大于外括号 (5)#的优先性低于与其相邻的算符,算符优先关系表,GE:EE+E|E-E|E*E|E/E|EE|(E)|i,步骤,符号栈,输入符号串,动作,1) # i+i*i# #i,移进,2) #i +i*i# #+,规约,3) #E +i*i# #+,移进,4) #E+ i*i# +i,移进,5) #E+i *i# +*,规约,6) #E+E *i# +*,移进,7) #E+E* i# *i,移进,

9、8) #E+E*i # *#,规约,9) #E+E*E # +#,规约,10) #E+E # #,规约,11) #E # 接受,对输入串i+i*i的算符优先分析过程,GE:EE+E|E-E|E*E|E/E|EE|(E)|i,算符文法 定义:如果不含空产生式的文法G中没有形如UVW的产生式,其中V,WVN,则称G为算符文法OG(Operator Grammar)。 性质1:在算符文法中任何句型都不包含两个相邻的非终结符.(数学归纳法) 性质2:如Vx或xV出现在算符文法的句型中,其中VVN,xVT,则中任何含x的短语必含有V.(反证法),算符优先关系在OG中定义算符优先关系x y,如果G中有形如

10、Uxy或U xVy的产生式。x y,如果G中有形如UxW的产生式,而W+y.或W+Vyx y,如果G中有形如U Wy的产生式,而W+x或W+xV 规定:若S+x或S+Vx,则# x若S+x或S+xV,则x #,算符优先文法在OG文法G中,若任意两个终结符间至多有一种算符优先关系存在,则称G为算符优先文法OPG(Operator Precedence Grammar)。注意:允许b c, c b;不允许b c, b c, b c,例 试说明下述算术表达式文法GE是一个算符文法,但不是算符优先文法。 GE: EE+EE*E(E)i解答 由于文法GE中的任何产生式右部都不含两个相邻的非终结符,所以G

11、E是算符文法。此外,因为(1) 由于存在EE+E,而E+E中的第二个E可推出EE*E,即有+ *;(2) 由于存在EE*E,而E*E中的第一个E可推出 EE+E,即有+ *。此即运算符+和*之间同时存在着两种不同的优先关系,故文法GE不是一个算符优先文法。,算符优先关系表的构造两个概念:FIRSTOP(P) = aP+a或P+Qa, aVT而QVN,表示首先遇到的终结符集。LASTOP(P)= aP+a或P+aQ, aVT而QVN,表示最后遇到的终结符集。注意:与FIRST集和FOLLOW集的区别,FIRSTOP集的构造方法:(1) 若有产生式Pa或PQa,则aFIRSTOP(P);(2) 若

12、aFIRSTOP(Q),且产生式PQ,则aFIRSTOP(P)。 LASTOP集构造方法:(1) 若有产生式Pa或PaQ,则aLASTOP(P);(2) 若aLASTOP(Q),且PQ,则aLASTOP(P)。,构造优先关系表的方法:(1) 对形如Pab或PaQb的产生式,有a b;(2) 对形如PaR的产生式,如果bFIRSTOP(R),则a b;(3) 对形如PRb的产生式,如果aLASTOP(R),则a b。# # ;若aFIRSTOP(S),则# a;若aLASTOP(S),则a #。,例 试构造下述算术表达式文法GE的算符优先关系表。GE:EE+TTTT*FFF(E)i,EE+TT

13、TT*FF F(E)i,(1) 构造FIRSTOP集FIRSTOP(F)=(, i;FIRSTOP(T)=*FIRSTOP(F)=*,(,i;FIRSTOP(E)=+FIRSTOP(T)=+,*,(,i。(2) 构造LASTOP集LASTOP(F)=),i;LASTOP(T)=*LASTOP(F)=*,),i;LASTOP(E)=+LASTOP(T)=+,*,),i。,EE+TT TT*FF F(E)i,(3) 构造优先关系表。 根据规则(1)知:由“(E)”得( )。 根据规则(2)知:由E+T得+ FIRSTOP(T),即:+ *,+ (,+ i;由T*F得* FIRSTOP(F),即:*

14、 (,* i;由F(E得( FIRSTOP(E),即:( +,( *,( (,( i。,EE+TT TT*FF F(E)i, 根据规则(3)知:由EE+得LASTOP(E) +,即:+ +,* +,) +,i +;由TT*得LASTOP(T) *,即:* *,) *,i *;由FE)得LASTOP(E) ),即:+ ),* ),) ),i )。此外,# #;# FIRSTOP(E),即# +,# *,# (,# i;LASTOP(E) #,即+ #,* #,) #,i #。,优先关系表,EE+TT TT*FF F(E)i,算符优先分析算法的设计 算符优先分析法不是一种规范归约的分析方法,它实际

15、上不是用句柄来刻画“可归约串”,而是用最左素短语来刻画“可归约串”。 算符优先文法的句型 # N1a1N2a2NnanNn+1# 其中,每个ai都是终结符,而Ni则是可有可无的非终结符。,素短语要素:仅包含终结符的子序列。每个素短语要素ajaj+1ai满足: aj-1 ajaj+1ai ai+1 最左素短语:(1) 至少包含一个终结符(是否包含非终结符则按短语的要求确定);(2) 除自身外不得包含其它素短语(最小性);(3) 在句型中具有最左性。,算符优先分析算法符号栈S,用来存放终结符和非终结符,k代表符号栈S的使用深度:k=1; Sk=#;do把下一个输入符号读进a中;if (SkVT)

16、j=k; else j=k1;/*任何两终结符之间最多只有一非终结符,故若SkVT则Sk1VT */,while (Sj a)do/*找最左子串Sj Sj+1Sk a*/Q=Sj;if (Sj1VT) j=j1;else j=j2;while (Sj Q);把Sj+1Sk归约为某个N;k=j+1;Sk=N;/*将归约后的非终结符N压栈*/,if (Sj a) | (Sj a) /*如果栈顶Sj a或Sj a则将a压栈*/k=k+1;Sk=a;else error( );while (a!=#);,例 算术表达式文法GE ,给出输入串i+i*i的算符优先分析过程。GE:EE+TTTT*FFF(E

17、)i,i+i*i算符优先分析过程,EE+TT TT*FF F(E)i,结论 算符优先分析的归约只关心句型中由左至右终结符序列的优先关系,而不涉及终结符之间可能存在的非终结符,即实际上可认为这些非终结符是同一个非终结符。 算符优先分析比规范归约要快得多,因为算符优先分析认为所有非终结符都是一样的,即跳过了所有形如PQ的单非终结符产生式所对应的归约步骤。这既是算符优先分析的优点,同时也是它的缺点;因为这样有可能把本来不成句子的输入串也误认为是句子,但这种缺点易于弥补。 算符优先分析法适用于分析算术表达式。,优先函数 动机:用优先关系表来表示每对终结符之间的优先关系存储量大(n+1)2)、查找费时。

18、如果给每个终结符赋一个值(即定义终结符的一个函数f),值的大小反映其优先关系,则终结符对a、b之间的优先关系就转换为两个优先函数f(a)与g(b)值的比较(2(n+1)。 好处: (1) 节省空间; (2) 便于进行比较运算。,左优先函数f(a)和右优先函数g(b) 定义:如果根据一个文法的算符优先关系表,使得文法中的每个终结符a和b满足下述条件: (1) 如果存在a b,则有f(a)=g(b); (2) 如果存在a b,则有f(a) g(b); (3) 如果存在a b,则有f(a) g(b)。 f称为入栈函数,g称为比较函数。 注意:对应一个优先关系表的优先函数f和g不是惟一的;只要存在一对

19、,就存在无穷多对。也有许多优先关系表不存在对应的优先函数。,例如,下面的优先关系表就不存在优先函数。假定存在f和g,则应有: f(a)=g(a); f(a) g(b) f(b)=g(a); f(b)=g(b) 将导致矛盾:f(a)g(b)=f(b)=g(a)=f(a),构造优先函数f和g 由定义直接构造优先函数 对每个终结符a(包括“#”),令f(a)=g(a)=1(也可以是其它整数),则: 如果a b而f(a) g(b),则令f(a)=g(b)+1; 如果a b而f(a) g(b),则令g(b)=f(a)+1; 如果a b而f(a)g(b),则令 f(a)=g(b)=maxf(a),g(b)

20、; 重复步直到过程收敛。如果重复过程中有一个值大于2n,则表明该算符优先文法不存在优先函数。,例 用定义法求出下面的优先关系表所对应的优先函数(不含“#”)。,优先函数表,4.6 LR分析法,LR分析法是一种自底向上进行规范归约的语法分析方法,LR指“自左向右扫描和构造最右推导的逆过程”。优点:LR分析法比递归下降分析法、LL(1)分析法和算符优先分析法对文法的限制要少得多,对大多数用无二义的上下文无关文法描述的语言都可以用LR分析器予以识别,而且速度快,并能准确、及时地指出输入串的任何语法错误及出错位置。缺点:若用手工构造分析器则工作量相当大,因此必须求助于自动生成LR分析器的生成器。,LR

21、分析器 分析栈:栈的每一项包括一个状态s和一个文法符号X(终结符或非终结符) 。 分析表:包括 “动作”(ACTION)表和“状态转换”(GOTO)表两部分。ACTIONs,a规定了当状态s面临输入符号a时应采取什么动作,而GOTOs,X规定了状态s面对文法符号X时的下一状态是什么。GOTOs,X定义了一个以文法符号为字母表的DFA。 总控程序:按分析栈的栈顶状态s和现行输入符号a执行ACTIONs,a所规定的动作。,LR分析器结构示意,分析器的动作 (1) 移进:使(s, a)的下一状态s=ACTIONs, a和输入符号a进栈,下一输入符号变成现行输入符号。 (2) 归约:指用某一产生式A进

22、行归约。假若的长度为,则归约的动作是栈顶的个项出栈,状态sm-变成栈顶状态,然后使(sm-,A)的下一状态s=GOTOsm-,A 和文法符号A进栈。归约的动作不改变现行输入符号,执行归约的动作意味着呈现于栈顶的符号串Xm-+1Xm是一个相对于A的句柄。 (3) 接受:分析成功,停止分析器的工作。 (4) 报错:发现错误,调用出错处理程序。,sm,sm-+1,sm-,s0,Xm,Xm-+1,Xm-,#,s,A,例如,表达式文法GE如下:GE: (1) EE+T(2) ET(3) TT*F(4) TF(5) F(E)(6) Fi,LR分析表,i+i*i的LR分析过程,LR文法对于一个文法,如果能够

23、构造一张LR分析表,使得它的每个入口均是惟一确定的,则称这个文法为LR文法。对于一个LR文法,当分析器对输入串进行自左至右扫描时,一旦句柄呈现于栈顶,就能及时对它实行归约。,注意 1)很多上下文无关文法不是LR文法,但典型的程序设计语言一般均可用LR文法描述。 2)LR分析法对文法的要求不象自顶向下的LL(1)分析法那么严格,LR分析法的文法范围要广一些。对于LR(k)文法,我们必须通过向前看k个输入符号才能够知道一个产生式的右部所能推导的所有字符串,进而识别出这个产生式右部的出现。而LL(k)文法要求只要看到了产生式右部推出的前k个符号后就能识别出用于推导的产生式。,LR分析表 (1) LR

24、(0)分析表:局限性很大,但它是建立一般LR分析表的基础; (2) SLR(1)分析表(即简单LR表):这种方法较易实现又极有使用价值; (3) LR(1)表(即规范LR表):这种表适用大多数上下文无关文法,但分析表体积庞大; (4) LALR表(即向前LR表):该表能力介于SLR(1)和LR(1)之间。,LR(0)分析表的构造 活前缀:规范句型的一个前缀,这种前缀不含句柄之后的任何符号。 文法GS中,若S*RA*R,的前缀称为G的活前缀。 例如,前面表达式文法GE的句型E+F*i可能的活前缀有:,E,E+,E+F,在LR分析工作过程中的任何时候,栈里的文法符号X1X2Xm应该构成活前缀,把输

25、入串的剩余部分匹配于其后即应成为规范句型。因此,只要输入串的已扫描部分保持可归约成一个活前缀,就意味着所扫描的部分没有错误。 对于一个文法GS,可以构造一个DFA来识别GS的所有活前缀。可以使用项目集作为状态构造一个DFA用来识别文法的所有活前缀。,项目:文法G的LR(0)项目(item),是在G的产生式右部的某处加点的产生式。 例如,产生式AXYZ对应有四个项目:AXYZAXYZAXYZAXYZ 但是产生式A只对应一个项目A。一个项目指明了在分析过程的某个时刻我们已经看到了产生式所能推导出的字符串的多大一部分。,AXYZ AXYZ AXYZ AXYZ,例如,上面第一个项目表示我们希望下一步从

26、输入中看见由XYZ推导出的字符串,第二个项目表示我们刚从输入中看见了由X推导出的字符串,下面希望看见由YZ推导出的字符串。 项目分类 移进项目:形如A a的项目。 待约项目:形如A B的项目。 归约项目:圆点在最右端的项目,形如A 。 接受项目:对文法的开始符号S的归约项目,形如S 。,规范LR(0)项目集族(项目集合的集合)的构造 项目集:把文法的所有项目划分成项目集,每个项目集对应语法分析器的一个状态。 规范LR(0)项目集族:一个文法的全体项目集构成的集合。 拓广文法:如果文法G的开始符号是S,那么G的拓广文法G是在G的基础上增加一个新的开始符号S和产生式SS。 如果GS是GS的拓广文法

27、,会有一个仅含项目SS的状态,就是惟一的“接受”态。,对文法进行拓广的目的是为了对某些右部含有开始符号的文法,在归约过程中能分清是否已归约到文法的左部开始符号,还是文法右部出现的开始符号,拓广文法的开始符号S只在左部出现,这样确保了不会混淆。 有效项目:如果存在规范推导S*Aw12w,则说项目A12对活前缀1是有效的。 若项目AB对活前缀是有效的,且有产生式B,则项目B对也是有效的。,闭包运算closure:假定I是文法GS的任一项目集,则构造I的闭包closure(I)的方法是: (1) I的任何项目都属于closure(I); (2) 若AB属于closure(I),那么对任何关于B的产生

28、式B,项目B也属于closure(I)。反复运用该规则,直至closure(I)不再增大为止。 AB在closure(I)中表示在语法分析的某一时刻,下一步应该从输入中看见的是B推出的串。如果B是一个产生式,也应该从输入串中看见从推出的串。所以,把B加入到closure(I)。,例 考虑拓广的表达式文法:EE EE+T | TTT*F | FF(E) | id 若项目集I=EE,则closure(I)包含项目:EEEE+T ETTT*F TFF(E) Fid,核心项目:初始项目SS和所有圆点不在最左端的项目。 非核心项目:点在左端的非初始项目。 每个项目集都可以通过求核心项目集的闭包得到。这样

29、,如果扔掉所有非核心项目,可以用较少的存储空间来表示需要的项目集,因为非核心项目可以通过求闭包来重新生成。 goto函数: goto(I, X) = closure(AX | AXI), 即把I中圆点在X前面的项目的圆点移到X后面得到的项目作为核心项目,然后求核心项目的闭包得到的项目集。,EE EE+T | T TT*F | F F(E) | id,例 若I是两个项目的集合EE, EE+T,则goto(I,+)包含以下项目:EE+TTT*FTFF(E)Fid 把EE+T中的点移过+得到EE+T,然后取它的闭包。,规范LR(0)项目集族构造算法 procedure items(G)beginC:

30、=closure(SS);repeatfor C的每个项目集I和每个文法符号X doif goto(I,X)非空且不在C中把goto(I,X)加入C中until 没有更多的项目集可以加入Cend,例 表达式文法的规范LR(0)项目集族。 I0:EE I1: EE I4: F(E)EE+T EE+T EE+TET I2: ET ETTT*F TT*F TT*FTF I3: TF TFF(E) F(E)Fid Fid,I5: Fid I8: F(E)I6: EE+T EE+TTT*F I9: EE+TTF TT*FF(E) I10: TT*FFid I11: F(E)I7: TT*FF(E)Fid

31、,识别活前缀的DFA 对每个文法G,规范项目集族的goto函数定义了一个确定的有穷自动机D,识别G的活前缀。D=(C,VNVT, goto, I0, C),其中C=I0, I1, , In是文法G的规范项目集族,所有文法符号构成DFA的字母表,goto函数就是DFA的转换函数,I0=closure(SS)是初态,C里面的每个项目集都是终态。,同一个项目可能对多个活前缀有效。 A12对活前缀1有效说明在发现1在分析栈时是移进还是归约,特别是,如果2,暗示句柄还没有完全进栈,动作应该是移进。如果2=,那么1是句柄,应该用这个产生式归约。如果I是对某个活前缀的有效项目集,那么goto(I,X)是对活

32、前缀X有效的项目集。如果D是一个由规范项目集族构造、以goto函数为转换函数的DFA,则一个活前缀的有效项目集正好从D的初态出发,沿着标记为的路径所能到达的项目集。,移进归约冲突:移进和归约项目同时存在。形如: AaB由于这时面临输入符号为a时不能确定移进a还是把归约为B。归约归约冲突:同时存在两个不同的归约项目。形如: AB不管面临什么输入符号都不能确定归约为A,还是归约为B。,LR(0)分析表的构造LR(0)文法:若一个文法GS的拓广文法GS的规范LR(0)项目集族中每个项目集不含任何冲突项目,则称GS是一个LR(0)文法。对于LR(0)文法,我们可直接从它的规范项目集族C和识别活前缀的自

33、动机的状态转换函数goto构造出LR分析表。,LR(0)分析表构造算法 假定C=I0,I1,In。令每个项目集Ik的下标k作为分析器的状态,特别地,令包含项目SS(表示整个句子还未输入)的项目集Ik的下标k为分析器的初态。分析表的ACTION子表和GOTO子表可按如下方法构造: (1) 若项目Aa属于Ik且goto(Ik,a)=Ij,a为终结符,则置ACTIONk,a为“将(j,a)移进栈”,简记为“sj”。 (2) 若AS,并且有项目A属于Ik,则对任何终结符a(或结束符#),置ACTIONk,a为“用产生式A进行归约”,简记为“rj”(注意:j是产生式的编号)。,(3) 若项目SS属于Ik

34、(S表示整个句子已输入并归约结束),则置ACTIONk,#为“接受”,简记为“acc”。 (4) 若goto(Ik,A)=Ij,A为非终结符,则置GOTOk,A=j。 (5) 分析表中凡不能用规则(1)(4)填入的空白表格均置为“出错标志”。 按上述方法构造的分析表的每个入口都是惟一的(即不含多重定义)。我们称如此构造的分析表是一张LR(0)表,使用LR(0)表的分析器叫做一个LR(0)分析器。,例 已知文法GS如下,试构造该文法的LR(0)分析表:GS: SBBBaBb解答 将文法GS拓广为文法GS:GS: (0) SS(1) SBB(2) BaB(3) Bb,(0) SS (1) SBB

35、(2) BaB (3) Bb,列出GS的所有项目:1SS 5SBB 9Bb2SS 6BaB 10Bb3SBB 7BaB4SBB 8BaB用闭包运算构造GS的规范项目集族如下: I0: SS I1: SS I3: BaB I5: SBBSBB I2: SBB BaB I6: BaBBaB BaB BbBb Bb I4: Bb,识别文法GS活前缀的DFA,LR(0)分析表,SLR(1)分析表的构造 动机:LR(0)语法分析器能够分析的文法要求每一项目集都不含冲突性的项目。对文法的限制过高,即使是定义算术表达式这样的简单文法也不是LR(0)的。需要研究一种分析能力更强的分析法,对文法有更少的限制。S

36、LR(1)分析法就是简单的LR分析法。 思想:许多冲突性的动作都可以通过考察有关非终结符的FOLLOW集而获得解决。,例 实型变量声明文法 real ,i i 缩写并拓广 (0)SS (1)SrD (2)DD,i (3)Di,当用句柄rD归约成S时,如果S的跟随符集合中不包含当前所有移进项目的移进符号,则这种移进归约冲突便可解决。 例中FOLLOW(S)=#,移进符号集合为,,这样,在状态3,面临,时移进,面临#时归约。,假定LR(0)项目集族的一个项目集I中含有m个移进项目: A1a11,A2a22,Amammn个归约项目: B11, B22, , Bnn如果集合a1,am、FOLLOW(B

37、1)、FOLLOW(Bn)两两不相交,则隐含在I中的动作冲突可通过检查现行输入符号a属于上述n+1个集合中的哪个集合而获得解决。,SLR(1)冲突解决方法:(1) 若a是某个ai,i=1,2,m,则移进;(2) 若aFOLLOW(Bi),i=1,2,n,则用产生式Bii进行归约;(3) 对(1)、(2)项以外的情况,报错。,构造SLR(1)分析表 先把GS拓广为GS,对GS构造LR(0)规范项目集族C和识别活前缀的自动机的状态转换函数goto,然后再使用C和goto按下面的算法构造GS的SLR(1)分析表。 假定C=I0,I1,In,令每个项目集Ik的下标k为分析器的一个状态,则GS的SLR(

38、1)分析表含有状态0,1,n。令那个含有项目SS的Ik的下标k为初态,则函数ACTION和GOTO可按如下方法构造:,(1) 若项目Aa属于Ik且goto(Ik, a)=Ij,a为终结符,则置ACTIONk,a为“将状态j和符号a移进栈”,简记为“sj”。 (2) 若AS,且项目A属于Ik,那么对任何输入符号a,aFOLLOW(A),置ACTIONk,a为“用产生式A进行归约”,简记为“rj”。其中,j是产生式的编号。 (3) 若项目SS属于Ik,则置ACTIONk,#为“接受”,简记为“acc”。 (4) 若goto(Ik, A)=Ij,A为非终结符,则置GOTOk,A=j。 (5) 分析表

39、中凡不能用规则(1)(4)填入信息的空白表格均置上“出错标志”。,按上述算法构造的含有ACTION和GOTO两部分的分析表,如果每个入口不含多重定义,则称它为文法GS的一张SLR(1)表,具有SLR(1)表的文法GS称为一个SLR(1)文法。数字“1”的意思是在分析过程中最多只要向前看一个符号,使用SLR(1)表的分析器叫做一个SLR(1)分析器。若按上述算法构造的分析表存在多重定义的入口(即含有动作冲突),则说明文法GS不是SLR(1)的;在这种情况下,不能用上述算法构造分析器。,(0)SS (1)SrD (2)DD,i (3)Di,例 构造实型变量声明文法的SLR(1)分析表。 FOLLO

40、W(S)=#; FOLLOW(S)=#; FOLLOW(D)=, #。,SLR(1)分析表,LR(1)分析表的构造 动机:在SLR(1)方法中,如果项目集Ik含有A,那么在状态k时,只要所面临的输入符号aFOLLOW(A),就确定采取“用A归约”的动作。但在某种情况下,当状态k呈现于栈顶时,栈里的符号串所构成的活前缀未必允许把归约为A,因为可能没有一个规范句型含有前缀Aa。因此,在这种情况下,用A进行归约未必有效。,例:文法G(0) S S(1) S aAd(2) S bAc(3) S aec(4) S bed(5) A e 规范LR(0) 项目集族(识别G的活前缀的DFA):,I5: S a

41、e c A e S S aAd aed (S S bAc)S S aec I7: S be d A e S S bAc bec (S S aAd)S S bed ?特定句型中哪些输入符号能跟在句柄之后,例如,考虑下面的文法GS (1) SL=R (2) SR (3) L*R (4) Li (5) RL 将文法GS拓广为GS后,构造文法GS的规范LR(0) 项目集族。,I2:SL=R RL,I2中的项目RL,=FOLLOW(R)。于是,当语法分析器处于状态2而且下一个输入符号为=时,SLR语法分析器调用RL归约。然而,文法没有以R=开始的右句型。因此,仅与活前缀L相对应的状态2不应该执行把L归约

42、成R的归约动作。 思想:可以令该状态蕴涵更多的信息,使之能够剔除上述那些用A进行的无效归约。必要时,可以通过分裂状态,使LR语法分析器的每个状态能确切地指出句柄后紧跟哪些终结符时才可能把归约为A。,LR(1)项目 每个LR(1)项目的一般形式为 A,a其中A是产生式,a是终结符或#,这个分量叫做项目的搜索符。 搜索符对于的项目A,a没有影响。对于形如A,a的项目,搜索符则表示只有下一个输入符号为a时,才能使用A进行归约。这样的a的集合总是FOLLOW(A)的一个子集,可能是真子集。,LR(1)项目A,a对活前缀有效,如果存在规范推导S*A,其中: (1) =, (2) a是的第一个符号,或者=

43、且a=#。 例如,文法GS: SBBBaBb 有最右推导S*aaBabaaaBab,故项目BaB, a对活前缀aaa是有效的。 有最右推导S*BaBBaaB,故项目BaB, #对于活前缀Baa是有效的。,closure(闭包)运算 (1) I的任何项目都属于closure(I)。 (2) 若项目AB, a属于closure(I),B是一个产生式,那么对于FIRST(a)中的每个终结符b,如果B, b原来不在closure(I)中,则把它加进去。 (3) 重复执行步骤(2),直到closure(I)不再增大为止。 goto函数 goto(I,X)=closureAX, a | AX, aI,LR

44、(1)项目集族构造算法 procedure items(G)beginC:=closure(SS, #);repeatfor C的每个项目集I和每个文法符号X doif goto(I,X)非空且不在C中把goto(I,X)加入C中until 没有更多的项目集可以加入Cend,LR(1)分析表构造算法 假定C=I0,I1,In,令每个Ik的下标k为分析表的状态,含有S S,#的Ik的k为分析器的初态。动作ACTION和状态转换GOTO可按如下方法构造: (1) 若项目Aa, b属于Ik且goto(Ik,a)=Ij,a为终结符,则置ACTIONk, a为“将状态j和符号a移进栈”,简记为“sj”; (2) 若AS,项目A, a属于Ik,则置ACTIONk,a为“用产生式A归约”,简记为“rj”;其中,j是产生式的编号;,(3) 若项目SS,#属于Ik,则置ACTIONk,#为“接受”,简记为“acc”; (4) 若goto(Ik, A)=Ij,A为非终结符,则置GOTOk, A=j; (5) 分析表中凡不能用规则(1)(4)填入信息的空白栏均填上“出错标志”。 按上述算法构造的分析表,若不存在多重定义入口的情形,则称它是文法GS的一张规范的LR(1)分析表,使用这种分析表的分析器叫做一个规范的LR分析器,具有规范的LR(1)分析表的文法称为一个LR(1)文法。,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报