一个语法分析器的实现

来源:互联网 发布:100部网络删除小说rar 编辑:程序博客网 时间:2024/05/20 06:51

语法分析设计文档

LR分析法分LR(0),SLR(1),LALR,LR(1)好几种,具体是SLR(1)分析法,对于LR分析法来说,语法分析过程都由一个称为“总控程序”来完成的

总控程序是LR分析法的核心处理模块,而LR分析表又是总控程序的核心部分,所以整个LR分析法的核心部分就是求出LR分析表,下面就首先说明LR分析表的构造

 

给定文法(注意这里的标号表示的是第几条归约式,后面会用到!):

1.E -> E+T2.E -> E-T3.E -> T4.T -> T*F 5.T -> T/F 6.T -> F7.F -> (E) 8.F -> i

文法的项目集:

E’ -> E(注意这个E’,其实目的就是说推导从这里开始)E -> E+TE -> E-TE -> TT -> T*F T -> T/F T -> FF -> (E) F -> i

项目集规范族(这个跟书本上的是一样的,最好是自己先推一下):

I0:E’ -> .E    I1(下一步接收E)E -> .E+TI1E -> .E-TI1E -> .TI2(下一步接收T)T -> .T*F I2T -> .T/F I2T -> .FI3(下一步接收F)F -> .(E) I4(下一步接收左括号)F -> .iI5(下一步接收i)I1:E’ -> E.E -> E.+TI6(下一步接收+)E -> E.-TI7(下一步接收-)I2:E -> T.T -> T.*F I8(下一步接收*)T -> T./F I9(下一步接收/)I3:T -> F.I4:F -> (.E) I10(下一步接收E)E -> .E+TI10E -> .E-TI10E -> .TI2(这个状态以前出现过)T -> .T*F I2T -> .T/F I2T -> .FI3F -> .(E) I4F -> .iI5I5:F -> i.I6:E -> E+.TI11(下一步接收T)T -> .T*F I11T -> .T/F I11T -> .FI3F -> .(E) I3F -> .iI5I7:E -> E-.TI12(下一步接收T)T -> .T*F I12T -> .T/F I12T -> .FI3F -> .(E) I4F -> .iI5I8:T -> T*.F I13(下一步接收F)F -> .(E) I4F -> .iI5I9:T -> T/.F I14(下一步接收F)F -> .(E) I4F -> .iI5I10:F -> (E.) I15(下一步接收右括号)E -> E.+TI6E -> E.-TI7I11:E -> E+T.T -> T.*F I8T -> T./F I9I12:E -> E-T.T -> T.*F I8T -> T./F I9I13:T -> T*F .I14:T -> T/F .I15:F -> (E) .

 

这个推导过程应该没问题吧?如果有问题,仔细再检查一下!好,这个推导过程其实对于LR(0),SLR(1),LALR,LR(1)都是必经的一步,而且都是一样的,真正不一样的地方就体现在最终的分析表上

 

问题:这个文法是LR(0)文法吗?如果不是,那么它是SLR(1)文法吗?(请务必先自己认真思考一下,再看解答,因为这个问题很关键!)

 

解答:

从上述的项目集规范族观察I2,I11,I12:

I2:E -> T.T -> T.*F I8(下一步接收*)T -> T./F I9(下一步接收/)I11:E -> E+T.T -> T.*F I8T -> T./F I9I12:E -> E-T.T -> T.*F I8T -> T./F I9


注意到没有?对于I2,从I2状态出发,接收了T后,可以到达I8和I9状态,那么到底应该前往哪一个状态呢?

于是这个文法不是LR(0)文法!(I11和I12的分析同理)


要证明是不是SLR(1)文法,先求Follow集

Follow(E) = {+,-,),#}(# 是终结符)


因为E -> E+T

所以Follow(E)是Follow(T)的子集(就是E有的T里也要有)

Follow(T) = {+,-,),*,/,#}(# 是终结符)


因为T -> T*F

所以Follow(T)是Follow(F)的子集

Follow(F) = {+,-,),*,/,#}(# 是终结符)


好了,现在可以构造SLR(1)分析表了,先给出这个表


回顾项目集规范族,一步步填表:

1. 从I0出发,接收E到达I1,于是在状态栏0列,GOTO表E列填入1;接收T到达I2,同理填入2;接收F到达I3,同理填入3;接收左括号到达I4,在ACTION表(列填入S4;接收i到达I5,在ACTION表i列填入S5

2. 从I1出发,因为这里第一条“E’-> E.”意味着文法被接受(Accept),所以(1,#)填入ACC,表示到达此状态文法被接受,对应的(1,+)填入S6,(1,-)填入S7

3. 从I2出发,因为这个状态会导致冲突,因此要使用SLR(1)分析法消除冲突

对于“E -> T.”,还记得Follow(E)吧,现在就在(2,#)和(2,Follow(E))的所有元素,即(2,+),(2,-),(2,))上填入R3(R3表示将其归约为第三条归约式,还记得前面的标号吧)

对于:

T -> T.*F       I8(下一步接收*)

T -> T./F       I9(下一步接收/)

直接在(2,*)上填入S8,(2,/)上填入S9


我想到这里,你应该自己推出整个表了吧!不信?自己推一次!上述有错漏之处,望指正!


既然有了分析表,现在就要使用总控程序对输入串进行语法分析了,分析表中有Si和rj大家都知道的。S是shift的缩写,也就是移进,R是reduce的缩写,也就是规约。规约是推导的逆操作。

先来看看在进行分析的时候S和R操作的规则

Si:移进,把i移入到状态栈,把a移入到符号栈。其中i,j表示状态号。
Ri:归约,用第i个产生式归约,同时状态栈与符号栈退出相应个符号,并把GOTO表相应状态和第i个产生式的左部非终结符入栈。


分析输入串“((i+i))”进行语法分析(我手写的分析过程和LemonParser的一样,直接上图吧)


 

第一步,符号栈中是#,输入符号串就是给定的要分析的串,状态栈因为从0开始,所以状态栈直接填0,应该知道,LR分析是从左到右扫描的。所以心里想着一根指针p,p首先指向输入串的‘(’,然后我们查ACTION表的(0,‘(’),0就是状态0,‘(’就是指针的当前字符。分析表中的(0,‘(’)是S4,填入第一步的ACTION,并且动作列填入移进,根据规则,将4入状态栈,‘(’入符号栈
    进入第二步,指针p肯定要前进一步了,所以输入符号串就进入b了,此步同上一步,不多解释
    关键是进入第四步后,此时,符号栈中为#((i,输入符号串是+i))#,状态栈是0445,此时去查ACTION表,查得(5,+),5是状态栈顶,+是p指针的当前位置。发现是R8,根据规则,用第8条产生式F -> i来规约。把动作栏GOTO先填了,同时状态栈与符号栈退出相应个符号,也即是说,把状态栏的栈顶5退出来,同时符号栈的i也退出,心里想着,不填表,并把GOTO表相应状态和第8个产生式的左部非终结符F入栈。GOTO表需要查的是(4,F)=3,8是R8的8,F是第8个产生式的左部。所以,就把3入状态栈,F入符号栈
  
    后面的都是一样的,不解释了,想明白这个过程,多动手是必需的,你也手工试试吧


SLR(1)的语法分析器:



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 微信电话费充错了怎么办 支付宝电话费充错了怎么办 在淘宝上充错电话费了怎么办 话费1000充错了怎么办 东西掉在地铁上怎么办 高铁安检丢东西怎么办 东西掉成都地铁上怎么办 东西掉在成都地铁上怎么办 成都地铁上掉东西了怎么办 地铁站丢了东西怎么办 在地铁站丢了东西怎么办 没有签劳动合同不发工资怎么办 没有劳动合同辞职不给工资怎么办 地铁安检要交押金怎么办 在广州地铁上人走丢了怎么办 海尔全自动洗衣机程系乱了怎么办 河南危险化学品经营许可证怎么办 甲方不给付监理费怎么办 甲方不按合同付工程款怎么办 撞车对方全责不赔钱怎么办 电梯坏了没人修怎么办 电工超作证丢了怎么办 设计师直接找电梯厂家怎么办 研究生补助申请期限过了怎么办 我的电脑图标没了怎么办 苹果锁频密码忘了怎么办 孕妇被降职降薪怎么办 公司降职降薪员工不同意怎么办 企业因为经营不善要降薪该怎么办 调岗不降薪我该怎么办? 怀孕后强制调岗怎么办 有限公司法人变更后债务怎么办 有限公司法人跑路债务怎么办 网上买票身份信息待核验怎么办 微信买票身份核验失败怎么办 买高铁票待核验怎么办 网上购票身份待核验怎么办 b站稿件版权原因怎么办 已离职老板打电话说账有问题怎么办 开到应急刹车道怎么办 自动挡的车刹车失灵怎么办