《编译原理课程教案》第4章:LR分析方法.ppt
《《编译原理课程教案》第4章:LR分析方法.ppt》由会员分享,可在线阅读,更多相关《《编译原理课程教案》第4章:LR分析方法.ppt(144页珍藏版)》请在三一办公上搜索。
1、LR分析方法,第四章(3),本章要求,主要内容:LR分析方法及其相关概念,语法分析器的自动生成,各种语法分析中的错误处理重点掌握:LR分析方法与分析过程,活前缀、LR(0)项目、Closure 和 go函数的定义,项目集规范族及识别活前缀的有穷自动机的构造,LR(0)分析表的构造,SLR文法及其分析表的构造。,LR分析概述,LR分析法:L从左向右扫描输入串,R构造最右推导的逆过程大多数用上下文无关文法描述的高级语言的语法成分可以用LR分析器来识别。LR分析:采用移进-归约分析,严格的规范归约。LR分析根据当前分析栈中的符号串和向右顺序查看输入串的K(K0)个符号就可以唯一确定分析的动作是移进还
2、是归约。向前查看0个符号,就是LR(0)分析方法,向前查看1个符号,就是LR(1)方法。,LR分析的优缺点,优点:比其他“移进-归约”方法使用广泛,识别率高能用LL(1)分析法分析的所有文法都能使用LR方法来进行分析。LR分析法在扫描输入串时就能发现其中的任何错误,并能准确地指出出错位置。缺点:手工构造分析表工作量太大。必须使用自动生成器。,自底向上分析法的关键问题是如何确定句柄。LR分析法与算符优先方法一样,LR方法也是通过求句柄逐步归约来进行语法分析。在算符优先分析中,通过算符的优先关系得到句柄“最左素短语”,LR方法中句柄是通过识别活前缀而求得。,LR分析方法的基本思想是:在规范归约过程
3、中,一方面记住已移进和归约出的整个符号串(历史),另一方面又根据所用产生式推测未来可能碰到的输入符号(对未来的展望)。当某一符号串类似于句柄出现在栈顶时,需要根据已记载的“历史”、“展望”和“现实”的输入符号三方面的内容来决定栈顶的符号串是否构成了真正的句柄,是否需要归约。一个LR分析器的组成见下图。,1、LR分析方法的逻辑结构,一个LR分析器由3个部分组成:LR分析程序,又称总控程序。所有的LR分析器都是相同的。分析表(分析函数),不同的文法分析表不同,同一个文法采用的LR分析器不同时,分析表也不同,分析表又可分为动作表(ACTION)和状态转换(GOTO)表两个部分,它们都可用二维数组表示
4、。分析栈,包括文法符号栈和相应的状态栈,它们均是先进后出栈。,状态栈:(S0,#)为预先放到栈中的初始状态和符号。,文法符号:X1X2Xm是目前已移进并归约出的句型部分。其实它是多余的,已经概括到状态里。,分析器实际上是一个带有先进后出栈的确定的有穷自动机。将“历史”和“展望”综合成“状态”,分析栈用来存放状态,状态概括了从分析开始直到某一归约阶段的全部历史和展望资料,不必象算符优先分析法中要翻阅栈中的内容才能决定是否要进行归约。只需根据栈顶状态和输入符号就可以唯一决定下一个动作。,总控程序根据分析表的内容来决定其下一步的处理动作,分析表是根据具体的文法按某种规则构造出来的。LR方法:根据具体
5、文法的分析表对输入串进行分析处理。LR分析过程:在总控程序的控制下,从左到右扫描输入符号串,根据分析栈中的状态和当前输入符号,按分析表中的内容完成相应的分析工作。,2.分析表的组成:,表中actionSi,aj,指出如果当前栈顶为状态Si,输入符号为aj时应执行的动作。其动作有四种可能,分别为:移进(S)、归约(r)、接受(acc)、出错(error)。,(1)分析动作表Action是一个二维数组,表中gotoSi,xj指出状态为Si,遇到Xj时应转到的下一状态。显然:分析表定义了一个以文法符号为字母表的DFA,(2)状态转换表goto 也是一个二维数组,ri表示按第i个产生式进行归约,Si表
6、示把当前输入符号移进栈,第i个状态进状态栈。,i表示转第i个状态,即第i个状态进状态栈。,空白表示分析动作出错,例:LR的Action和GoTo表,(1)E E+T(2)E T(3)T T*F(4)T F(5)F(F)(6)F i,产生式的序号,设文法为GL:,用三元式:(状态栈,符号栈,输入符号串)表示分析过程中状态栈,符号栈,输入符号串的变化初始时,将状态S0和#进分析栈。三元式为:(S0,#,a1a2an#)任一时刻的三元式为:(S0S1Sm,#X1X2Xm,aiai+1an#)分析器的下一步动作是由栈顶状态Sm和当前面临的输入符号ai唯一确定的。,3、LR分析过程:,移进:当前输入符号
7、ai移进符号栈,将action表中指出的状态S进状态栈。(S0S1SmS,#X1X2Xmai,ai+1an#),根据Sm和ai查action表,actionSm,ai有4种情况:,出错:报告出错信息。三元式的变化过程终止。,接受:分析成功,终止分析。三元式不再变化。,归约:若产生式A的右端长度为r,则两个栈顶的r个元素同时出栈,A进符号栈;再根据Sm-r和A查goto表,S=gotoSm-r,A进状态栈。三元式变为:(S0S1 Sm-r S,#X1X2Xm-rA,aiai+1an#),LR分析器示例:,文法G(E):(1)EET(2)ET(3)TT*F(4)TF(5)F(E)(6)Fi,其LR
8、分析表为:,sj::把下一状态j和现行输入符号a移进桟。,rj::按第j个产生式进行规约。,acc:接受。,空白格:出错标志。,若a为终结符,则GOTOs,a的值已列在ACTIONs,a的sj之中(状态j),因此,GOTO表仅对所有非终结符A列出GOTOs,A的值。,假定输入串为i*i+i,LR分析器的工作过程:步骤状态桟 符号桟输入串(1)0#i*i+i#(2)05#i*i+i#(3)03#F*i+i#(4)02#T*i+i#(5)027#T*i+i#,i,*,归约 指用某产生式A进行归约.假若的长度为r,归约动作是,去除栈顶r个项,使状态sm-r变成栈顶状态,然后把(sm-r,A)的下一状
9、态s=GOTOsm-r,A和文法符号A推进栈。,假定输入串为i*i+i,LR分析器的工作过程:步骤状态符号输入串(5)027#T*i+i#(6)0275#T*i+i#(7)02710#T*F+i#(8)02#T+i#(9)01#E+i#(10)016#E+i#,+,i,步骤状态符号输入串(10)016#E+i#(11)0165#E+i#(12)0163#E+F#(13)0169#E+T#(14)01#E#(15)接受,+,i,i,为了介绍LR分析过程,直接给出该文法的分析表,以后再介绍如何生成,例:LR的具体分析过程:,(1)E E+T(2)E T(3)T T*F(4)T F(5)F(F)(6
10、)F i,设文法为GL:,根据上述分析表,对输入串 i*i+i 的分析过程如下:,LR文法:对一个文法,如果能够构造一个分析表,且它的每个入口均是唯一的如何构造LR分析表?,4.3.1 LR(0)项目集族和LR(0)分析表的构造,假定是文法G的一个句子,我们称序列 n,n-1,0 是的一个规范归约,如果此序列满足:1 n=2 0为文法的开始符号,即0=S 3 对任何i,0 i n,i-1是从i经把句柄替换成为相应产生式左部符号而得到的。,LR(0)分析就是在分析的每一步,只需根据当前桟顶状态而不必向前查看输入符号就能确定应采取的分析动作。,规范归约过程中栈内的符号串和扫描剩下的输入符号串构成了
11、一个规范句型。栈内的如果出现句柄(最左直接短语),句柄一定在栈的顶部。,栈内永远不会出现句柄之后的符号!,字的前缀:是指字的任意首部,如字abc的前缀有,a,ab,abc活前缀:是指规范句型的一个前缀,这种前缀不含句柄之后的任何符号。即,对于规范句型,为句柄,如果=u1u2ur,则符号串u1u2ui(1ir)是的活前缀。(必为终结符串)。在LR分析工作过程中的任何时候,桟里的文法符号(自桟底而上)X1X2Xm应该构成活前缀,把输入串的剩余部分配上之后即应成为规范句型(如果整个输入串确实构成一个句子)。,引入一个新的概念:规范句型的活前缀,为什么?,因为首先规约的是句柄。,为什么要引入活前缀的概
12、念?,因为句柄是活前缀的后缀,识别活前缀就可以找到句柄;找到了句柄,就可以对句柄归约。,对于一个文法G,可以构造一个有限自动机DFA,它能识别G的所有活前缀。在这个基础上,我们再研究如何把这种自动机转变成LR分析表。,构造LR(0)分析表的基本思想是:从给定的上下文无关文法直接构造识别文法所有规范句型的活前缀的DFA,然后再将DFA转换为一张LR(0)分析表。,文法G的每个产生式的右部添加一个圆点称为G的一个LR(0)项目(简称项目)。如:AXYZ有四个项目:A.XYZ AX.YZ AXY.Z AXYZ.一个项目指明了在分析过程的某个时刻看到产生式的多大一部分。为什么要引入项目的概念?,LR(
13、0)项目,为什么要引入项目的概念?,活前缀与句柄之间的关系有三种情况:活前缀中已含有句柄的全部符号,表明此时某一规则A的右部符号串已出现在桟顶,其相应的分析动作是用此规则进行规约。(2)活前缀中只含句柄的一部分符号,此时意味着形如A12规则的右部子串1已出现在桟顶,正期待着从剩余的输入串中移进2;(3)活前缀中全然不含有句柄的任何符号,此时意味着期望从剩余输入串中能看到由某规则A的右部所推出的符号串。为了刻画在分析过程中,文法的某一规则的右部符号串已有多大一部分被识别,我们可在文法的每个规则的右部适当位置上加一个圆点来表示。针对上述活前缀与句柄之间关系的三种情况,标有圆点的规则分别是:(1)A
14、.(2)A1.2(3)A.,由于不同的LR(0)项目反映了在分析过程中桟顶的不同状态,因此,可以根据圆点的位置和圆点后是终结符还是非终结符,将一个文法的全部LR(0)项目进行分类(4类):(1)A.称为“归约项目”规约项目表示文法的某一个规则的右部已分析完,句柄已形成,应按次规则进行规约。(2)归约项目 S.称为“接受项目”接受项目是对文法开始符号的规约项目。(3)A.a(aVT)称为“移进项目”移进项目表示期待从输入串中移进一个符号,以待形成句柄。(4)A.B(BVN)称为“待约项目”.待约项目表示期待从剩余的输入串中规约而得到B,然后才能继续分析A的右部。,文法G(S)SE EaA|bB
15、AcA|d BcB|d 该文法的项目有:1.SE2.SE3.EaA 4.EaA5.EaA6.AcA7.AcA8.AcA9.Ad 10.Ad11.EbB12.EbB13.EbB14.BcB15.BcB 16.BcB17.Bd18.Bd,有效项目,我们说项目A 1.2对活前缀1是有效的,其条件是存在规范推导,指规范推导。,有效项目中的圆点“.”,意味着对应产生式中的“.”所在处就是这个活前缀的终止点。,项目A1.2对活前缀1有效,具有两层含意:从文法开始符号,经1可到达该项目(项目所在状态);在当前活前缀的情况下,该项目可指导下一步分析动作(A=12)。,有效项目的意义:1.到目前为止分析是正确的
16、;2.指导下一步的分析:(1)规约项目A1.对活前缀1是有效的,意味着我们应把符号串1规约为A,即把活前缀1变成A;(2)移进项目A1.2对活前缀1是有效的,意味着句柄尚未形成,下一步动作应是移进。,活前缀与项目的关系:一个项目可能对若干个活前缀有效 项目A1.2对所有从初态出发可以到达此项目的路径上的标记均有效(一个路径标记是一个活前缀)。若干个项目可能对同一个活前缀有效 项目集中的所有项目对同一活前缀均有效。,综合可知:同一项目集中的所有项目,对此项目集的所有活前缀均有效。即,项目集中的每个项目均有同等权利指导下一步动作。,同一项目可能对好几个活前缀都是有效的,此时,该项目出现在好几个不同
17、的LR(0)项目集中。(用子集法对NFA的确定化过程中,某个状态会出现在多个状态子集中吗?)同一活前缀,是否存在多个项目对它都是有效的?如果存在的话,并且不同项目告诉我们应做的事情各不相同,就会产生冲突。这种冲突通过向前多看几个输入符号,或许能够解决,这种情形就是LR(K)文法;对于非LR文法,不论超前看几个输入符号都绝对无法解决冲突。,在识别活前缀的DFA中,一个活前缀的有效项目集就是从该DFA的初态出发,经读出后而到达的那个项目集(状态)。换言之,在任何时候,分析栈中的活前缀X1X2 Xm的有效项目集正是栈顶状态Sm所代表的那个集合。也正是从识别活前缀的DFA的初态出发,读出X1X2 Xm
18、后到达的那个项目集(状态)。即,桟顶的项目集(状态)体现了桟里的一切有用信息历史。(这是LR分析理论的一条基本定理。),文法G(S)SE EaA|bB AcA|d BcB|d 考虑:在该文法的活前缀识别自动机DFA(见前图)中,符号串bc是一个活前缀,这个DFA(见前图)在读出这个串后到达状态5。状态5含有三个项目:B c.BB.cB B.D,我们分析这个项目集对bc的有效性。S E bB bcB(表明B c.B 的有效性。)S E bB bcB bccB(表明B.cB的有效性。)S E bB bcB bcd(表明B.d 的有效性。),项目A 1.2对活前缀1是有效的,其条件是存在规范推导,对
19、于一个文法G,可以构造一个有限自动机DFA,它能识别G的所有活前缀。在这个基础上,我们再研究如何把这种自动机转变成LR分析表。,构造LR(0)分析表的基本思想是:从给定的上下文无关文法直接构造识别文法所有规范句型的活前缀的DFA,然后再将DFA转换为一张LR(0)分析表。,步骤一:构造识别文法所有活前缀的NFA,我们可以使用文法的LR(0)项目构造一个NFA,用来识别这个文法的所有活前缀。构造方法如下:(1)规定文法中开始符号S仅在第一个产生式左部出现(拓广文法),将含有S的并且圆点出现在最左边的项目作为NFA的唯一初态;(2)文法的任何项目均认为是NFA的状态(活前缀识别态);(3)规定所有
20、那些圆点出现在最右边的项目为NFA的终态(句柄识别态);,(4)如果状态i和j出自同一产生式,而且状态j的圆点只落后于状态i的圆点一个位置,如状态i为 XX1 Xi-1.Xi Xn 而状态j为XX1 Xi-1Xi.Xi+1 Xn,则从状态i画一条标志为Xi的有向边到状态j;(5)若状态i为X.A,A为非终结符,则从状态i画一条边到所有状态A.(即,所有那些圆点出现在最左边的A的项目)。,6:AcA,7:AcA,8:AcA,9:Ad,10:Ad,4:EaA,5:EaA,3:EaA,2:SE,11:EbB,12:EbB,13:EbB,14:BcB,15:BcB,16:BcB,18:Bd,17:Bd
21、,识别活前缀的NFA,1:SE,文法G:SE EaA|bB AcA|d BcB|d,6,7,8,9,10,4,5,3,1,2,11,12,13,14,15,16,18,17,a,A,E,b,B,B,c,A,c,d,识别活前缀的NFA,句柄识别态(即,这个活前缀的后半截含有句柄。),即:每个产生式是一个识别活前缀的NFA;每个项目是NFA的一个状态。,于是:所有产生式构成文法G识别活前缀的NFA集合。,使用第二章介绍的子集法,可以将识别活前缀的NFA确定化,使之成为一个以项目集合为状态的DFA。这个DFA就是建立LR分析算法的基础。,步骤二:把识别文法所有活前缀的NFA确定化。,这个DFA就是建
22、立 LR(0)分析表的基础。,构成识别一个文法活前缀的DFA的项目集(状态)的全体称为文法的LR(0)项目集规范族。这个规范族是建立LR(0)分析表的基础。,LR(0)项目集规范族,LR(0)项目集规范族的另一个构造方法,先假定文法G是一个以S为开始符号的文法,我们构造一个G,它包含了整个G,但它引进了一个不出现在G中的非终结符S,并加进一个新产生式SS,而这个S是G的开始符号。那么,我们称G是G的拓广文法。这样,便会有一个仅含项目SS.的状态,这就是唯一的“接受”态。,前述构造LR(0)项目集规范族的方法是:列出拓广文法的所有项目,按规定原则构造其NFA,然后再确定化为DFA,该DFA的所有
23、状态即为该文法的LR(0)项目集规范族。这种方法的工作量很大。我们现在研究一种新的更为简单直接的方法来构造LR(0)项目集规范族。,我们发现如下规律:若状态中包含形如AB的待约项目,则形如B的项目也在此状态内。例如0状态中项目集为:SE,EaA,EBb,我们研究识别活前缀的DFA,分析其每个状态中项目集的构成。,回顾NFA的构造规则中,(5)若状态i为X.A,A为非终结符,则从状态i画一条边到所有状态A.。这与第三章中介绍的-闭包概念是一致的。即EaA和EbB正是属于SE的闭包中。因而,我们也可用闭包函数来求DFA中一个状态的项目集。,假定I是文法G的任一项目集,定义和构造I的闭包CLOSUR
24、E(I)如下:1.I的任何项目都属于CLOSURE(I);2.若AB属于CLOSURE(I),那么,对任何关于B的产生式B,项目B也属于CLOSURE(I);3.重复执行上述两步骤直至CLOSURE(I)不再增大为止。,P50:NFA确定化设I是的状态集的一个子集,定义I的-闭包-closure(I)为:i)若sI,则s-closure(I);ii)若sI,则从s出发经过任意条弧而能到达的任何状态s都属于-closure(I)-closure(I)=Is|从某个sI出发经过任意条弧能到达s,2.若状态i为X.A,A为非终结符,则从状态i画一条边到所有状态A.。,用上述方法,我们可以很容易构造出
25、初态的项目集,即SS属于I,再按上述三点求其闭包。有了初态的项目集,其它状态的项目集如何求出?回顾在构造识别活前缀的NFA时,除了箭弧上标记为的外,其它两个相邻状态对应的项目都是出自同一个产生式,只是圆点的位置相差1。箭弧上的标记为前一个状态和后一个状态对应项目的圆点间的符号。,(4)如果状态i和j出自同一产生式,而且状态j的圆点只落后于状态i的圆点一个位置,如状态i为 XX1 Xi-1.Xi Xn 而状态j为XX1 Xi-1Xi.Xi+1 Xn,则从状态i画一条标志为Xi的有向边到状态j;,而识别活前缀的DFA的每个状态是一个项目集,项目集中的每个项目都不相同,每个项目圆点后的符号不一定相同
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译原理课程教案 编译 原理 课程 教案 LR 分析 方法
链接地址:https://www.31ppt.com/p-6528797.html