JAVA实现SLR(1)文法的分析器

代码功能:

(1)计算非终结符的FIRST和FOLLOW集

(2)构造SLR分析表

(3)判断该文法是否为SLR文法

(4)输入字符串,按照SLR分析法判断该字符串的语法是否正确,并给出判断过程

代码的思路:

  1. 将文法中的每一个句子的左部和右部进行分离。其中,右部的每一个终结符和非终结符也是单独保存的。
  2. 将左部和右部分离后的文法中的终结符和非终结符识别出来。一般左部都是非终结符,那么右部除去非终结符就是终结符了。
  3. 计算FIRST集。设置一个变量_ALTERED_,在每次有新的终结符添加到FIRST集中的时候,就将_ALTERED_置位true。计算FIRST集的方法如下:如果产生式右部是终结符a,且这个终结符a不在FIRST集中,则添加。如果是非终结符A,则将A的FIRST集中的所有自己没有的终结符添加到自己的FIRST集中。如果A的终结符中包含ε,则继续判断下一个。
  4. 计算FOLLOW集。设置一个变量_ALTERED_,在每次有新的终结符添加到FOLLOW集中的时候,就将_ALTERED_置位true。计算FOLLOW集的方法如下:1、遍历文法中的所有产生式,所有出现在非终结符右边的终结符加入到相应follow集中,如果非终结符右边没有东西,则把$加入。 2、遍历文法中的所有产生式,若产生式最右边是非终结符,把左部非终结符的follow集的所有元素都添加到对应非终结符中。3、将$加入到第一个非终结符的follow集中。
  5. 根据每一条产生式,生成项目集规范族程序设计的是对项目集规范族中的每一个项目集中的每一条项目都进行分析,产生了新的项目集就添加到项目集规范族中。
  6. 根据项目集规范族和FOLLOW集生成SLR分析表。根据·的位置判断是否将其添加到SLR分析表中,很容易。如果·后面的是终结符,将转移动作s添加到SLR分析表中的ACTION部分;如果·后面的是终结符,将转移添加到SLR分析表的GOTO部分;如果·在项目的末尾,将归约动作r添加到SLR分析表的ACTION部分。
  7. 设计词法分析器,用于分析输入的程序。
  8. 根据SLR分析表和词法分析的结果进行词法分析。

程序代码:

CSDN下载了直接用Eclipse打开:https://download.csdn.net/download/oLOVED/12098174

GitHub上的项目:https://github.com/z1178902213/SLRAnalyser-

程序运行:

文法:

E->E+T
E->E-T
E->T
T->T*K
T->T/K
T->K
K->K%F
K->K^F
K->F
F->(E) 
F->id
F->num

测试程序:

a+xyz*10+(c/d)+(xyz%a)+(d^5)

运行结果:

终结符:[+, -, *, /, %, ^, (, ), id, num]
非终结符:[E, T, K, F]
文法如下所示:
(1)E->E+T
(2)E->E-T
(3)E->T
(4)T->T*K
(5)T->T/K
(6)T->K
(7)K->K%F
(8)K->K^F
(9)K->F
(10)F->(E)
(11)F->id
(12)F->num

文法的First集为:
First(E) = { ( id num }
First(T) = { ( id num }
First(K) = { ( id num }
First(F) = { ( id num }

文法的Follow集为:
Follow(E) = { + - ) $ }
Follow(T) = { $ * / + - ) }
Follow(K) = { $ % ^ * / + - ) }
Follow(F) = { $ % ^ * / + - ) }

该文法的项目集规范族如下所示:
I0:
START->·E
E->·E+T
E->·E-T
E->·T
T->·T*K
T->·T/K
T->·K
K->·K%F
K->·K^F
K->·F
F->·(E)
F->·id
F->·num

I1:
START->E·
E->E·+T
E->E·-T

I2:
E->T·
T->T·*K
T->T·/K

I3:
T->K·
K->K·%F
K->K·^F

I4:
K->F·

I5:
F->(·E)
E->·E+T
E->·E-T
E->·T
T->·T*K
T->·T/K
T->·K
K->·K%F
K->·K^F
K->·F
F->·(E)
F->·id
F->·num

I6:
F->id·

I7:
F->num·

I8:
E->E+·T
T->·T*K
T->·T/K
T->·K
K->·K%F
K->·K^F
K->·F
F->·(E)
F->·id
F->·num

I9:
E->E-·T
T->·T*K
T->·T/K
T->·K
K->·K%F
K->·K^F
K->·F
F->·(E)
F->·id
F->·num

I10:
T->T*·K
K->·K%F
K->·K^F
K->·F
F->·(E)
F->·id
F->·num

I11:
T->T/·K
K->·K%F
K->·K^F
K->·F
F->·(E)
F->·id
F->·num

I12:
K->K%·F
F->·(E)
F->·id
F->·num

I13:
K->K^·F
F->·(E)
F->·id
F->·num

I14:
F->(E·)
E->E·+T
E->E·-T

I15:
E->E+T·
T->T·*K
T->T·/K

I16:
E->E-T·
T->T·*K
T->T·/K

I17:
T->T*K·
K->K·%F
K->K·^F

I18:
T->T/K·
K->K·%F
K->K·^F

I19:
K->K%F·

I20:
K->K^F·

I21:
F->(E)·

SLR分析表:

栈                                输入        动作
0                                         a+xyz*10+(c/d)+(xyz%a)+(d^5)$        移进
0id6                                      +xyz*10+(c/d)+(xyz%a)+(d^5)$        按F->[id]归约
0F4                                       +xyz*10+(c/d)+(xyz%a)+(d^5)$        按K->[F]归约
0K3                                       +xyz*10+(c/d)+(xyz%a)+(d^5)$        按T->[K]归约
0T2                                       +xyz*10+(c/d)+(xyz%a)+(d^5)$        按E->[T]归约
0E1                                       +xyz*10+(c/d)+(xyz%a)+(d^5)$        移进
0E1+8                                     xyz*10+(c/d)+(xyz%a)+(d^5)$        移进
0E1+8id6                                   *10+(c/d)+(xyz%a)+(d^5)$        按F->[id]归约
0E1+8F4                                    *10+(c/d)+(xyz%a)+(d^5)$        按K->[F]归约
0E1+8K3                                    *10+(c/d)+(xyz%a)+(d^5)$        按T->[K]归约
0E1+8T15                                   *10+(c/d)+(xyz%a)+(d^5)$        移进
0E1+8T15*10                                 10+(c/d)+(xyz%a)+(d^5)$        移进
0E1+8T15*10num7                               +(c/d)+(xyz%a)+(d^5)$        按F->[num]归约
0E1+8T15*10F4                                 +(c/d)+(xyz%a)+(d^5)$        按K->[F]归约
0E1+8T15*10K17                                +(c/d)+(xyz%a)+(d^5)$        按T->[T, *, K]归约
0E1+8T15                                      +(c/d)+(xyz%a)+(d^5)$        按E->[E, +, T]归约
0E1                                           +(c/d)+(xyz%a)+(d^5)$        移进
0E1+8                                          (c/d)+(xyz%a)+(d^5)$        移进
0E1+8(5                                         c/d)+(xyz%a)+(d^5)$        移进
0E1+8(5id6                                       /d)+(xyz%a)+(d^5)$        按F->[id]归约
0E1+8(5F4                                        /d)+(xyz%a)+(d^5)$        按K->[F]归约
0E1+8(5K3                                        /d)+(xyz%a)+(d^5)$        按T->[K]归约
0E1+8(5T2                                        /d)+(xyz%a)+(d^5)$        移进
0E1+8(5T2/11                                      d)+(xyz%a)+(d^5)$        移进
0E1+8(5T2/11id6                                    )+(xyz%a)+(d^5)$        按F->[id]归约
0E1+8(5T2/11F4                                     )+(xyz%a)+(d^5)$        按K->[F]归约
0E1+8(5T2/11K18                                    )+(xyz%a)+(d^5)$        按T->[T, /, K]归约
0E1+8(5T2                                          )+(xyz%a)+(d^5)$        按E->[T]归约
0E1+8(5E14                                         )+(xyz%a)+(d^5)$        移进
0E1+8(5E14)21                                       +(xyz%a)+(d^5)$        按F->[(, E, )]归约
0E1+8F4                                             +(xyz%a)+(d^5)$        按K->[F]归约
0E1+8K3                                             +(xyz%a)+(d^5)$        按T->[K]归约
0E1+8T15                                            +(xyz%a)+(d^5)$        按E->[E, +, T]归约
0E1                                                 +(xyz%a)+(d^5)$        移进
0E1+8                                                (xyz%a)+(d^5)$        移进
0E1+8(5                                               xyz%a)+(d^5)$        移进
0E1+8(5id6                                               %a)+(d^5)$        按F->[id]归约
0E1+8(5F4                                                %a)+(d^5)$        按K->[F]归约
0E1+8(5K3                                                %a)+(d^5)$        移进
0E1+8(5K3%12                                              a)+(d^5)$        移进
0E1+8(5K3%12id6                                            )+(d^5)$        按F->[id]归约
0E1+8(5K3%12F19                                            )+(d^5)$        按K->[K, %, F]归约
0E1+8(5K3                                                  )+(d^5)$        按T->[K]归约
0E1+8(5T2                                                  )+(d^5)$        按E->[T]归约
0E1+8(5E14                                                 )+(d^5)$        移进
0E1+8(5E14)21                                               +(d^5)$        按F->[(, E, )]归约
0E1+8F4                                                     +(d^5)$        按K->[F]归约
0E1+8K3                                                     +(d^5)$        按T->[K]归约
0E1+8T15                                                    +(d^5)$        按E->[E, +, T]归约
0E1                                                         +(d^5)$        移进
0E1+8                                                        (d^5)$        移进
0E1+8(5                                                       d^5)$        移进
0E1+8(5id6                                                     ^5)$        按F->[id]归约
0E1+8(5F4                                                      ^5)$        按K->[F]归约
0E1+8(5K3                                                      ^5)$        移进
0E1+8(5K3^13                                                    5)$        移进
0E1+8(5K3^13num7                                                 )$        按F->[num]归约
0E1+8(5K3^13F20                                                  )$        按K->[K, ^, F]归约
0E1+8(5K3                                                        )$        按T->[K]归约
0E1+8(5T2                                                        )$        按E->[T]归约
0E1+8(5E14                                                       )$        移进
0E1+8(5E14)21                                                     $        按F->[(, E, )]归约
0E1+8F4                                                           $        按K->[F]归约
0E1+8K3                                                           $        按T->[K]归约
0E1+8T15                                                          $        按E->[E, +, T]归约
0E1                                                               $        接受
程序正确
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值