编译原理教案-LR分析_第1页
编译原理教案-LR分析_第2页
编译原理教案-LR分析_第3页
编译原理教案-LR分析_第4页
编译原理教案-LR分析_第5页
已阅读5页,还剩73页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

LR分析自下而上语法分析算法之复习:移进-归约分析文法G[S]:

(1)S→aAcBe

(2)A→b

(3)A→Ab

(4)B→dabbcde步骤符号栈输入符号串动作1)#abbcde#移进2)#abbcde#移进A3)#abbcde#归约(A→b)4)#aAbcde#移进A5)#aAbcde#归约(A→Ab)6)#aAcde#移进7)#aAcde#移进B8)#aAcde#归约(B→d)9)#aAcBe#移进11)#S#接受S10)#aAcBe#归约(S→aAcBe)分析符号串abbcde是否G[S]的句子对输入串abbcde#的移进-规约分析过程SaAcBeaAcdeaAbcdeabbcde在步骤3中,用A→b归约在步骤5中,用A→Ab归约问题:何时移进?何时归约?用哪个产生式归约?3)#abbcde#归约(A→b)5)#aAbcde#归约(A→Ab)4)#aAbcde#移进6)#aAcde#移进分析:已分析过的部分在栈中的前缀不同,而且移进和归约后栈中的状态会发生变化

我们引入一个新的状态栈来表示符号栈中的符号目前状态用LR分析表来表示不同状态下对于各输入符号应采取的动作步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S66)#aAcde#移进023S57)#aAcde#移进0235S89)#aAcBe#移进02357S911)#S#接受01acc对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r235)#aAbcde#归约(A→Ab)0236r338)#aAcde#归约(B→d)02358r4710)#aAcBe#归约(S→aAcBe)023579r11状态栈ACTIONGOTO文法G[S]:

(1)S→aAcBe

(2)A→b

(3)A→Ab

(4)B→dSi:移进,并将状态i进栈ri:用第i个产生式归约,同时状态栈与符号栈退出相应个符号,根据GOTO表将相应状态入栈步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S66)#aAcde#移进023S57)#aAcde#移进0235S89)#aAcBe#移进02357S911)#S#接受01acc对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r235)#aAbcde#归约(A→Ab)0236r338)#aAcde#归约(B→d)02358r4710)#aAcBe#归约(S→aAcBe)023579r11状态栈ACTIONGOTO文法G[S]:

(1)S→aAcBe

(2)A→b

(3)A→Ab

(4)B→dSi:移进,并将状态i进栈ri:用第i个产生式归约,同时状态栈与符号栈退出相应个符号,根据GOTO表将相应状态入栈问题:对于一个文法,状态集是如何确定的?LR分析表是如何得到的?可归前缀与活前缀文法G[S]:

(1)S→aAcBe[1]

(2)A→b[2]

(3)A→Ab[3]

(4)B→d[4]SaAcBe[1]

aAcd[4]e[1]

aAb[3]cd[4]e[1]

ab[2]b[3]cd[4]e[1]每次归约句型的前部分依次为:

ab[2]

aAb[3]

aAcd[4]

aAcBe[1]规范句型的这种前部分符号串称为可归前缀我们把形成可归前缀之前包括可归前缀在内的所有规范句型的前缀都称为活前缀,a,ab

,a,aA,aAb

,a,aA,aAc,aAcd

,a,aA,aAc,aAcB,aAcBe活前缀(ViablePrefixes)viable:adjcapableofgrowinganddeveloping<~seed>capableofbeingputintopractice:workable定义:S’A

是文法G中的一个规范推导,如果符号串是的前缀,则称是G的一个活前缀。LR分析需要构造识别活前缀的有穷自动机我们可以文法的终结符和非终结符都看成有穷自动机的输入符号,每次把一个符号进栈看成已识别过了该符号,同时状态进行转换,当识别到可归前缀时,相当于在栈中形成句柄,认为达到了识别句柄的终态。步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S66)#aAcde#移进023S57)#aAcde#移进0235S89)#aAcBe#移进02357S911)#S#接受01acc对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r235)#aAbcde#归约(A→Ab)0236r338)#aAcde#归约(B→d)02358r4710)#aAcBe#归约(S→aAcBe)023579r11状态栈ACTIONGOTO014235769SabAbcBed8*步骤符号栈输入符号串动作1)#abbcde#移进0S2对输入串abbcde#的LR分析过程状态栈ACTIONGOTO014235769SabAbcBed8*步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

对输入串abbcde#的LR分析过程状态栈ACTIONGOTO014235769SabAbcBed8*步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r23状态栈ACTIONGOTO014235769SabAbcBed8*步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S6对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r23状态栈ACTIONGOTO014235769SabAbcBed8*步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S6对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r235)#aAbcde#归约(A→Ab)0236r33状态栈ACTIONGOTO014235769SabAbcBed8*步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S66)#aAcde#移进023S5对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r235)#aAbcde#归约(A→Ab)0236r33状态栈ACTIONGOTO*014235769SabAbcBed8步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S66)#aAcde#移进023S57)#aAcde#移进0235S8对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r235)#aAbcde#归约(A→Ab)0236r33状态栈ACTIONGOTO*014235769SabAbcBed8步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S66)#aAcde#移进023S57)#aAcde#移进0235S8对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r235)#aAbcde#归约(A→Ab)0236r338)#aAcde#归约(B→d)02358r47状态栈ACTIONGOTO014235769SabAbcBed8*步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S66)#aAcde#移进023S57)#aAcde#移进0235S89)#aAcBe#移进02357S9对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r235)#aAbcde#归约(A→Ab)0236r338)#aAcde#归约(B→d)02358r47状态栈ACTIONGOTO014235769SabAbcBed8*步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S66)#aAcde#移进023S57)#aAcde#移进0235S89)#aAcBe#移进02357S9对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r235)#aAbcde#归约(A→Ab)0236r338)#aAcde#归约(B→d)02358r4710)#aAcBe#归约(S→aAcBe)023579r11状态栈ACTIONGOTO014235769SabAbcBed8*步骤符号栈输入符号串动作1)#abbcde#移进0S22)#abbcde#移进02S4

4)#aAbcde#移进023S66)#aAcde#移进023S57)#aAcde#移进0235S89)#aAcBe#移进02357S911)#S#接受01acc对输入串abbcde#的LR分析过程3)#abbcde#归约(A→b)024r235)#aAbcde#归约(A→Ab)0236r338)#aAcde#归约(B→d)02358r4710)#aAcBe#归约(S→aAcBe)023579r11状态栈ACTIONGOTO014235769SabAbcBed8*如何构造识别活前缀的有限自动机已经有了活前缀如何构造有限自动机?活前缀及其可归前缀的一般计算方法文法G[S]:

S’→S[0]

S→aAcBe[1]

A→b[2]

A→Ab[3]

B→d[4]句子abbcde的可归前缀如下:

S[0]

ab[1]

aAb[3]

aAcd[4]

aAcBe[1]构造识别其活前缀及可归前缀的有限自动机如下:104387131210182591461715161110SabaAbaAcdaAcBe*1*句子识别态i句柄识别态104387131210182591461715161110SabaAbaAcdaAcBe*X加上开始状态X确定化X13246859SabAbcBed7*识别活前缀的确定的有限自动机活前缀及其可归前缀的一般计算方法定义:文法G,AVN, LC(A)={|S’A,V*,VT*}规范推导中在非终结符A左边所有可能出现的符号串的集合推论:若文法G中有产生式B→A,则有

LC(A)LC(B)*{}文法G’[S]:

S’→S[0]

S→aAcBe[1]

A→b[2]

A→Ab[3]

B→d[4]由前面的定义与推论我们知:LC(S’)={}

LC(S)=LC(S’)*{}

LC(A)=LC(S)*{a}LC(A)*{}

LC(B)=LC(S)*{aAc}化简为:[S’]=

[S]=[S’]

[A]=[S]a+[A]

[B]=[S]aAc求解方程组可得:[S’]=

[S]=

[A]=a+[A]

[B]=aAc[A]=a|[A][A]=a*=a这样我们求出了每个非终结符在规范推导中用该非终结符的右部替换该非终结符之前,它的左部可能出现的所有前缀,也就是在规范归约过程中用句柄归约成该非终结符之前不包括句柄的活前缀。不包括句柄的活前缀+句柄=?可归前缀?令LR(0)C(A→)=LC(A)*{}文法G’的可归前缀有:

LR(0)C(S’→S)=[S’]*{S}={S}

LR(0)C(S→aAcBe)=[S]*{aAcBe}={aAcBe}

LR(0)C(A→b)=[A]*{b}={ab}

LR(0)C(A→Ab)=[A]*{Ab}={aAb}

LR(0)C(B→d)=[B]*{d}={aAcd}总结:如何构造识别文法活前缀的有限自动机?1、根据文法算出其可归前缀

2、根据可归前缀,构造识别文法活前缀的不确定有限自动机

3、确定化,从而构造出识别文法活前缀的确定的有限自动机参见课本P124的例子LR分析器的构造1、构造识别文法活前缀的确定有限自动机

2、根据该自动机构造相应的分析表(ACTION表、GOTO表)总控程序Action/Goto表输入符号串输出状态与符号栈这种方法构造识别可归前缀的有限自动机从理论的角度讲是比较严格的,但实现起来却很复杂是否存在一种比较实用的方法?由文法的产生式直接构造识别活前缀和可归前缀的有限自动机项目(item):在每个产生式的右部适当位置添加一个圆点构成项目例如:产生式S→aAcBe对应有6个项目

[0]S→

•aAcBe

[1]S→a•AcBe

[2]S→aA•cBe

[3]S→aAc•Be

[4]S→aAcB•e

[5]S→aAcBe•有限自动机的每一个状态由一个项目构成项目圆点的左部表示分析过程的某个时刻用该产生式归约时句柄已识别的部分,圆点右部表示待识别的部分。构造识别活前缀的NFA:

1、把文法的所有产生式的项目都引出,每个项目都为NFA的一个状态

2、确定初态、句柄识别态、句子识别态

3、确定状态之间的转换关系

*若项目i为X→X1X2...Xi-1

•Xi...Xn

项目j为X→X1X2...Xi-1Xi•

Xi+1...Xn

则从状态i到状态j连一条标记为Xi的箭弧

*若i为X

→•A,k为A→

•,则从状态i画标 记为的箭弧到状态k文法G‘:

S’E

ET+E

ET

Tint*T

Tint

T(E)文法的项目有:

1、S’

•E

2、S’E•

3、E•T+E

4、ET•+E

5、ET+•E

6、ET+E•

7、E•T

8、ET•

9、T•int*T

10、Tint•*T

11、Tint*•T

12、Tint*T•

13、

T•int

14、Tint•

15、T•(E)

16、T(•E)

17、T(E•)

18、T(E)•

NFAforViablePrefixesoftheExampleT®.(E)T®(.E)T®(E.)T®(E).(E)S’®E.E®.T+EE®T.+EE®T+.EE®T+E.S’®.EE®.TE®T.T®int.T®.intT®.int*TT®int*T.T®int*.TT®int.*TeeeeEeTeeeE+eintint*TeeeeeTeNFAforViablePrefixesinDetail(1)S’®.ENFAforViablePrefixesinDetail(2)S’®.ES’®E.EE®.TeE®.T+EeNFAforViablePrefixesinDetail(3)S’®E.E®.T+ES’®.EE®.TT®.int*TeeET®.(E)eT®.inteeE®T.TNFAforViablePrefixesinDetail(4)T®.(E)S’®E.E®.T+ES’®.EE®.TE®T.T®.intT®.int*TeeEE®T.+ETeeeeeeTNFAforViablePrefixesinDetail(5)T®.(E)T®(.E)(S’®E.E®.T+ES’®.EE®.TE®T.T®.intT®.int*TeeEeeeeeeTE®T.+ETNFAforViablePrefixesinDetail(6)T®.(E)T®(.E)(S’®E.E®.T+ES’®.EE®.TE®T.T®.intT®.int*TeeeeEeeeeeeTE®T.+ETT®(E.)ENFAforViablePrefixesinDetail(7)T®.(E)T®(.E)(S’®E.E®.T+ES’®.EE®.TE®T.T®.intT®.int*TeeeeEeeeeeeTE®T.+ETT®(E.)ET®(E).)NFAforViablePrefixesinDetail(8)T®.(E)T®(.E)(S’®E.E®.T+ES’®.EE®.TE®T.T®.intT®.int*TeeeeEeeeeeeTE®T.+ETT®(E.)ET®(E).)E®T+.E+NFAforViablePrefixesinDetail(9)T®.(E)T®(.E)(S’®E.E®.T+ES’®.EE®.TE®T.T®.intT®.int*TeeeeEeeeeeeTE®T.+ETT®(E.)ET®(E).)E®T+.E+eeE®T+E.ENFAforViablePrefixesinDetail(10)T®.(E)T®(.E)(S’®E.E®.T+ES’®.EE®.TE®T.T®.intT®.int*TeeeeEeeeeeeTE®T.+ETT®(E.)ET®(E).)E®T+.E+eeE®T+E.ET®NFAforViablePrefixesinDetail(11)T®.(E)T®(.E)(S’®E.E®.T+ES’®.EE®.TE®T.T®.intT®.int*TeeeeEeeeeeeTE®T.+ETT®(E.)ET®(E).)E®T+.E+eeE®T+E.ET®T®int.*TintNFAforViablePrefixesinDetail(12)T®.(E)T®(.E)(S’®E.E®.T+ES’®.EE®.TE®T.T®.intT®.int*TeeeeEeeeeeeTE®T.+ETT®(E.)ET®(E).)E®T+.E+eeE®T+E.ET®T®int.*TintT®int*.T*NFAforViablePrefixesinDetail(13)T®.(E)T®(.E)(S’®E.E®.T+ES’®.EE®.TE®T.T®.intT®.int*TeeeeEeeeeeeTE®T.+ETT®(E.)ET®(E).)E®T+.E+eeE®T+E.ET®T®int.*TintT®int*.T*T®int*T.Teee根据圆点所在的位置和圆点后是终结符还是非终结符把项目分为以下几种:移进项目,形如A→•a待约项目,形如A→•B归约项目,形如A→•

接受项目,形如S’→S•

TranslationtotheDFAS’®.EE®.TE®.T+ET®.(E)T®.int*TT®.intS’®E.E®T.E®T.+ET®int.*TT®int.T®(.E)E®.TE®.T+ET®.(E)T®.int*TT®.intE®T+E.E®T+.EE®.TE®.T+ET®.(E)T®.int*TT®.intT®int*.TT®.(E)T®.int*TT®.intT®int*T.T®(E.)T®(E).ET(intint*)EETint((intT+(T项目集构成识别一个文法活前缀的DFA项目集(状态)的全体称为这个文法的LR(0)项目集规范族NFA确定化为DFA的工作量较大,我们考虑直接构造出项目集作为DFA的状态,就可直接构造DFA通过闭包函数(CLOSURE)来求DFA一个状态的项目集如果I是文法G’的一个项目集,定义和构造I的闭包CLOSURE(I)如下:

a)I的项目都在CLOSURE(I)中

b)若A→•B属于CLOSURE(I),则每一形如B→•的项目也属于CLOSURE(I)

c)重复b)直到CLOSURE(I)不再扩大定义转换函数如下:

GOTO(I,X)=CLOSURE(J)

其中:I为包含某一项目集的状态,X为一文法符号

J={任何形如A→X•

的项目|A→•

X属于I}圆点不在产生式右部最左边的项目称为核,唯一的例外是S’→

•S。因此用GOTO(I,X)转换函数得到的J为转向后状态所含项目集的核使用闭包函数(CLOSURE)和转向函数(GOTO(I,X))构造文法G’的LR(0)的项目集规范族,步骤如下:a)置项目S’→

S为初态集的核,然后对核求闭包CLOSURE({S’→

S})得到初态的项目集

b)对初态集或其它所构造的项目集应用转换函数GOTO(I,X)=CLOSURE(J)求出新状态J的项目集

c)重复b)直到不出现新的项目集为止S’®.EE®.TE®.T+ET®.(E)T®.int*TT®.intS’®E.E®T.E®T.+ET®int.*TT®int.T®(.E)E®.TE®.T+ET®.(E)T®.int*TT®.intE®T+E.E®T+.EE®.TE®.T+ET®.(E)T®.int*TT®.intT®int*.TT®.(E)T®.int*TT®.intT®int*T.T®(E.)T®(E).ET(intint*)EETint((intT+(T总结:构造识别文法活前缀DFA的三种方法一、根据形式定义求出活前缀的正规表达式,然后由此正规表达式构造NFA再确定化为DFA二、求出文法的所有项目,按一定规则构造识别活前缀的NFA再确定化为DFA三、使用闭包函数(CLOSURE)和转向函数(GOTO(I,X))构造文法G’的LR(0)的项目集规范族,再由转换函数建立状态之间的连接关系得到识别活前缀的DFALR(0)项目集规范族的项目类型分为如下四种:1)移进项目A→•a2)待约项目A→•B3)归约项目A→•

4)接受项目S‘→S•

一个项目集可能包含多种项目a)移进和归约项目同时存在。移进-归约冲突b)归约和归约项目同时存在。归约-归约冲突LR(0)文法:若其LR(0)项目集规范族不存在移进-归约,或归约-归约冲突,称为LR(0)文法。LR(0)分析表的构造LR(0)分析表相当于识别活前缀的有限自动机DAF的状态转换矩阵LR(0)分析表的构造算法书上p130,倒数4行,

A→•改为A→•aLR(0)分析器的工作过程令包含S‘→•S

的项目集Ik的下标k为分析器的初态LR(0)分析表的ACTION和GOTO表的构造步骤如下:

a)若项目A→•a属于Ik,且转换函数GO(Ik,a)=Ij,当a为终结符时,则置ACTION[k,a]为Sj

b)若项目A→•属于Ik,则对a为任何终结符或‘#’,置ACTION[k,a]=rj,j为产生式在文法G‘中的编号

c)若GO(Ik,A)=Ij,则置GOTO[k,A]=j,其中A为非终结符,j为某一状态号

d)若项目S‘→S

•属于Ik,则置ACTION[k,#]=acc

e)其它填上“报错标志”S’®.EE®.TE®.T+ET®.(E)T®.int*TT®.intS’®E.E®T.E®T.+ET®int.*TT®int.T®(.E)E®.TE®.T+ET®.(E)T®.int*TT®.intE®T+E.E®T+.EE®.TE®.T+ET®.(E)T®.int*TT®.intT®int*.TT®.(E)T®.int*TT®.intT®int*T.T®(E.)T®(E).ET(intint*)EETint((intT+(1234567891011SLR(1)分析大多数适用的程序设计语言的文法不能满足LR(0)文法的条件,即其规范族中会有含有冲突的项目集(状态)如果解决这种冲突?直觉:对于有冲突的状态,向前查看一个符号,以确定采用的动作文法G‘:

(0)S’S

(1)SrD

(2)DD,i

(3)DiI0:

S‘→•S

S‘→•rDI2:

S→r•D

D

→•D,i

D→•iI3:

S→rD

D→D•,iI4:

D→i

•I5:

D→D,•iI1:

S‘→S•I6:

D→D,i

•SriD,iLR(0)分析表I3:

S→rD

D→D•,i向前查看一个符号,看其是否是S的后跟符号(FOLLOW(S)),若否则移进,是则归约。SLR(1)分析表一个LR(0)规范族中含有如下的项目集(状态)I

I={X→•b,A→•

,B→•

}

若有:FOLLOW(A)∩FOLLOW(B)=Ø

FOLLOW(A)∩{b}=Ø

FOLLOW(B)∩{b}=Ø状态I面临某输入符号a

1)若a=b,则移进

2)若aFOLLOW(A),则用产生式A→进行归约

3)若aFOLLOW(B),则用产生式B→进行归约

4)此外,报错若一个文法的LR(0)分析表中所含有的动作冲突都能用上述方法解决,则称这个文法是SLR(1)文法“改进的”SLR(1)分析:对所有非终结符都求出其FOLLOW集合,这样只有归约项目仅对面临输入符号包含在该归约项目左部非终结符的FOLLOW集合中,才采取用该产生式归约的动作。改进的SLR(1)分析表的ACTION表和GOTO表的构造步骤:

a)若项目A→•a属于Ik,且转换函数GO(Ik,a)=Ij,当a为终结符时,则置ACTION[k,a]为Sj

b)若项目A→•属于Ik,则对a为任何终结符或‘#’,且满足aFOLLOW(A)时,置ACTION[k,a]=rj,j为产生式在文法G‘中的编号

c)若GO(Ik,A)=Ij,则置GOTO[k,A]=j,其中A为非终结符,j为某一状态号

d)若项目S‘→S

•属于Ik,则置ACTION[k,#]=acc

e)其它填上“报错标志”仍有许多文法构造的LR(0)项目集规范族存在的动作冲突不能用SLR(1)方法解决LR(1)分析若项目集[A→•B]属于I时,则[B→•]也属于I把FIRST()作为用产生式归约的搜索符(称为向前搜索符),作为用产生式B→归约时查看的符号集合(用以代替SLR(1)分析中的FOLLOW集),并把此搜索符号的集合也放在相应项目的后面,这种处理方法即为LR(1)方法LR(1)项目集族的构造:针对初始项目S’→•S,#求闭包后再用转换函数逐步求出整个文法的LR(1)项目集族。1)构造LR(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论