4.5.5LALR(1)分析法LR(1)分析法虽然可以解决SLR(1)方法所难以解决的移进—归约或归约—归约冲突,但是对同一个文法而言,当搜索符不同时,使得同一个项目集被分裂成多个项目集从而引起状态数的剧烈增长,导致时间和内存空间的急剧上升,使其应用受到一定的限制,为了克服LR(1)分析法的这种缺点,我们可以采用LALR(1)分析法。4.5.5LALR(1)分析法LALR(1)分析法是界于SLR(1)分析法和LR(1)分析法之间的一种语法分析方法,这种分析法能解决SLR(1)分析法所不能解决的冲突动作,并且其分析表的状态个数与SLR(1)分析表的状态个数一样多。LALR(1)分析法的基本思想是对LR(1)项目集规范族中将所有同心的项目集合并为一,以减少项目集个数。4.5.5LALR(1)分析法所谓同心的LR(1)项目集是指在两个LR(1)项目集中,除搜索符不同之外,核心部分是相同的。例如,分析前例文法的LR(1)项目集族,可以发现同心集如下:0.S'→S3.L→*R1.S→L=R4.L→i2.S→R5.R→LI0:SI1:S'→S•,$LI2:S→L•=R,$R→L•,$I3:S→R•,$RI4:L→*•R,=/$R→•L,=/$L→•*R,=/$L→•i,=/$*I5:L→i•,=/$iiS'→•S,$S→•L=R,$S→•R,$L→•*R,=/$L→•i,=/$R→•L,$*I6:S→L=•R,$L→•*R,$L→•i,$R→•L,$I9:S→L=R•,$I11:L→*•R,$R→•L,$L→•*R,$L→•i,$I10:R→L•,$I12:L→i•,$I7:L→*R•,=/$I13:L→*R•,$I8:R→L•,=/$*LR(1)项目集族及转换函数=RLRL*LiR0.S′→S1.S→L=R2.S→R3.L→*R4.L→i5.R→LiI4与I11,I5与I12,I7与I13,I8与I10它们俩俩之间除了搜索符不同之外,“心”是相同的。将同心集合并为:4.5.5LALR(1)分析法I4,11:L→*•R,=/$R→•L,=/$L→•*R,=/$L→•i,=/$I5,12:L→i•,=/$I7,13:L→*R•,=/$I8,10:R→L•,=/$4.5.5LALR(1)分析法我们看到合并同心集后的项目集其核心部分不变,仅搜索符合并。对合并同心集后的项目集的转换函数为GO(I,X)自身的合并,这是因为相同的心之转换函数仍属同心集。例如GO(I4,11,i)=GO(I4,i)∪GO(I11,i)=I5,12GO(I4,11,R)=GO(I4,R)∪GO(I11,R)=I7,13GO(I4,11,*)=GO(I4,*)∪GO(I11,*)=I4,114.5.5LALR(1)分析法合并同心集需着重指出的是若文法是LR(1)文法,即它的LR(1)项目集中不存在动作冲突,合并同心集后若有冲突也只可能是归约—归约冲突而不可能是移进—归约冲突。假定LR(1)文法的项目集Ik与Ij为同心集,其中Ik={[A→α•,a1][B→β•aγ,b1]}Ij={[A→α•,a2][B→β•aγ,b2]}合并同心集后的项目集Ikj={[A→α•,a1/a2][B→β•aγ,b1/b2]}4.5.5LALR(1)分析法因为假设文法是LR(1)的,在Ik中{a1}∩{a}=Φ,在Ij中{a2}∩{a}=Φ,显然在Ikj中({a1}∪{a2})∩{a}=Φ这也就是说合并同心集以后,不可能有移进—归约冲突。但可能有归约—归约冲突。例如,可设想有两个同心的LR(1)项目集:4.5.5LALR(1)分析法现在我们可以根据合并同心集后的项目集族构造文法的LALR(1)分析表,其构造方法如下:Ik={[A→α•,a][B→α•,b]}Ij={[A→α•,b][B→α•,a]}合并同心集后的项目集Ikj={[A→α•,a/b][B→α•,a/b]}合并后产生了归约—归约冲突。4.5.5LALR(1)分析法2.若LR(1)项目集族中不存在含冲突的项目集,则合并所有同心集,构造出文法的LALR(1)项目集族。1.构造拓广文法G´的LR(1)项目集族。例如,对前例中文法G的LR(1)项目集族合并同心集后构造出的LALR(1)项目集族如下图所示。I0:0.S'→S1.S→L=R2.S→R3.L→*R4.L→i5.R→LSI1:S'→S•,$LI2:S→L•=R,$R→L•,$I3:S→R•,$RI4,11:L→*•R,=/$R→•L,=/$L→•*R,=/$L→•i,=/$*I5,12:L→i•,=/$iiS'→•S,$S→•L=R,$S→•R,$L→•*R,=/$L→•i,=/$R→•L,$*I9:S→L=R•,$I6:L→*•R,$R→•L,$L→•*R,$L→•i,$I7,13:L→*R•,=/$I8,10:R→L•,=/$LALR(1)项目集族及转换函数RLR=*Li4.5.5LALR(1)分析法4.LALR(1)项目集族构造该文法的LALR(1)分析表的方法与LR(1)分析表的构造方法相同。由图构造文法的LALR(1)分析表如下表所示。3.若LALR(1)项目集族中不存在归约—归约冲突,则该文法是LALR(1)文法。对例中的文法,由于合并同心集后不存在归约—归约冲突,所以该文法是LALR(1)文法。G[S]的LALR(1)分析表01234,115,1267,13ACTIONGOTOi*=$SLRS5,12S4,11123accS6r5r2S5,12S4,11r4r4S5,12S4,11r3r3r5r58,107,138,1098,109r1I0:0.S'→S1.S→L=R2.S→R3.L→*R4.L→i5.R→LSI1:S'→S•,$LI2:S→L•=R,$R→L•,$I3:S→R•,$RI4,11:L→*•R,=/$R→•L,=/$L→•*R,=/$L→•i,=/$*I5,12:L→i•,=/$iiS'→•S,$S→•L=R,$S→•R,$L→•*R,=/$L→•i,=/$R→•L,$*I9:S→L=R•,$I6:L→*•R,$R→•L,$L→•*R,$L→•i,$I7,13:L→*R•,=/$I8,10:R→L•,=/$LALR(1)项目集族及转换函数RLR=*Li4.5.5LALR(1)分析法对一给定的文法G,其LALR(1)分析表比LR(1)分析表状态数要少,但在分析文法G[S]的某一个含有错误的符号串时,LALR(1)分析速度比LR(1)分析速度要慢,为什么?4.5.6对二义性文法的应用与其相应的LR分析表一定含有多重定义的元素。如何利用这一缺点?任何一个二义性文法决不是LR类文法,我们知道4.5.6对二义性文法的应用E→E+E|E*E|(E)|id相应的非二义性文法为:E→E+T|TT→T*F|FF→(E)|id例如,考虑算术表达式的二义性文法4.5.6对二义性文法的应用2.二义性文法的LR分析表所含状态数肯定比非二义性文法少,因为非二义性文法含有右部仅只一个非终结符号的规则E→T和T→F,它们要占用状态和降低分析器的分析效率。两者相比,二义性文法的优点在于:1.若需改变运算符的优先级或结合性,无需改变文法自身。4.5.6对二义性文法的应用现在我们构造算术表达式二义性文法的LR(0)项目集规范族如下图所示:算术表达式二义性文法的LR(0)项目集规范族和转移函数I0:E'→·EE→·E+EE→·E*EE→·(E)E→·idI1:E'→E·E→E·+EE→E·*EI2:E→·E+EE→·E*EE→·(E)E→·idE→(·E)I3:E→id·I4:E→·E+EE→·E*EE→·(E)E→·idE→E+·EI5:E→·E+EE→·E*EE→·(E)E→·idE→E*·EI6:E→(E·)E→E·*EE→E·+EI7:E→E+E·E→E·*EE→E·+EI8:E→E*E·E→E·*EE→E·+EI9:E→(E)·E(id(id+id(I3I2﹡(idE+﹡E+﹡E﹡+)4.5.6对二义性文法的应用从图中可以看出状态I1,I7和I8中存在移进—归约冲突,I1中冲突可用SLR(1)方法解决。对I7和I8而言:因为FOLLOW(E')∩{+,*}=ф,即遇到输入符号为‘$’时则接受,遇到‘+’或‘*’时则移进。FOLLOW(E)∩{+,*}={$,+,*,)}∩{+,*}≠Φ由于有4.5.6对二义性文法的应用因而I7和I8中冲突不能用SLR(1)方法解决,也不能用其它LR(K)方法解决,但是我们用+,*的优先级和结合性可以解决这类冲突。4.5.6对二义性文法的应用那么在I7中,由于‘*’优先级高于‘+’,所以状态7面临‘*’移进,又因‘+’服从左结合,所以状态7面临‘+’则用E→E+E归约。若我们规定‘*’的优先级高于‘+’的优先级,且它们都服从左结合4.5.6对二义性文法的应用在I8中,由于‘*’优先于‘+’且‘*’服从左结合,因此状态8面临‘+’或‘*’都应用E→E*E归约。由此构造的该二义性文法的LR分析表如下表所示:4.5.6对二义性文法的应用二义性文法的LR分析表0S3S2112345r4r4r4r4S4S5S9S3S2r3r3r3r366789S4S5accr1S5r1r1S3S2S3S2r2r2r2r28状态GOTOACTIONE+id﹡()$74.5.6对二义性文法的应用其它的二义性文法也可用类似方法进行处理,可以构造出无多重定义的LR分析表。