编译原理SLR(1)文法的C++实现(基于SLR(1)分析法的语法制导翻译及中间代码生成程序设计原理与实现)

程序功能描述

完成以下描述赋值语句 SLR(1)文法语法制导生成中间代码四元式的过程。
G[A]:
A→V=E
E→E+T∣E-T∣T
T→T*F∣T/F∣F
F→(E)∣i
V→i
[设计说明] 终结符号i为用户定义的简单变量,即标识符的定义。
[设计要求]
(1)构造文法的SLR(1)分析表,设计语法制导翻译过程,给出每一产生式对应的语义动作;
(2)设计中间代码四元式的结构;
(3)输入串应是词法分析的输出二元式序列,即某赋值语句“专题1”的输出结果,输出为赋值语句的四元式序列中间文件;
设计两个测试用例(尽可能完备),并给出程序执行结果四元式序列。

 
主要数据结构描述
在实验中主要使用结构体进行各类属性的封装。此外,还用到了stack和list的结构,其中stack主要由数组进行简易实现,便于输出栈内内容;list使用C++ STL中的list进行动态的添加。以下对每一部分进行详细说明。
此处使用sentence结构体对于项目集族中的每个产生式的属性进行封装。finish表示该产生式是否完成规约,即点操作是否进行完毕;tag即用来表示当前点的位置,因产生式包含有左部和->符号,故从3开始计数;string类的str用于存储产生式的字符串。
typedef struct
{
int finish = 0;  //是否结束
int tag = 3;  //当前圆点的位置
string str;
}sentence;
此处用act结构体对构造的ACTION表进行存储。在实验中,我并没有使用二维数组进行ACTION表的存储,而是选用了一维的结构体:I代表输入的目前的状态,Vt代表输入的终结符号,tag用于表示是r类还是s类,action用于记录对应的r类的产生式标号或s类状态标号。
typedef struct
{
int I;  //当前状态
char Vt;  //终结符号
char tag;  //r||s
int action;  //动作
}act;
同上,此处使用结构体go对GOTO表进行存储。I表示输出的当前状态,Vn表示输入的非终结符,next_I表示GOTO的转移结果,形如GOTO(I, Vn) = next_I。
typedef struct
{
int I;  //当前状态
char Vn;  //非终结符
int next_I;  //转移状态
}go;
此处使用I进行构造项目集族时状态的存储。number对应于该项目的序号,如I0/I1等;l则为list类型,用于存储该状态中的产生式。
typedef struct
{
int number;  //编号
list l;
}I;  //状态
此处使用siyuanshi进行四元式的存储,形同四元式:(op, arg1, arg2, result)。在此不再赘述。
typedef struct
{
char op;
char arg1;
char arg2;
char result;
}siyuanshi;
此处使用var进行符号表的存储。在构造四元式的过程中,需要对于上一次的操作中新生成的结果进行记录,以便生成新的四元式时作为参数加入其中;故结构体中的name代表某一运算结果的变量名,如A/B/C/D;string类的value表示该变量对应的算术表达式(属性)。
typedef struct
{
char name;
string value;  //place
}var;  //变量
以下是一些变量的定义。在这些过程中用到了大量的list:首先进行状态集的定义,以list的形式对状态进行存储;之后是list-char的FIRST与FOLLOW集的定义;之后是list形式的ACTION表和GOTO表的定义,以及list-char的Vn/Vt集。最后,input用来存储输入串,在分析过程中也会使用input来主要进行分析。
list DFA;  //状态集
list *First;  //FIRST集
list *Follow;  //FOLLOW集
list ACTION;  //ACTION[i][j]
list GOTO;  //GO[i][j]
list Vt;  //终结符号集
list Vn;  //非终结符号集
char input[100];
下面是分析栈、符号栈以及其属性栈的定义,分别存储状态号、符号以及其代表的属性,并且设立栈顶指针。下面使用list结构进行四元式的存储、记录可以产生四元式的产生式标号以及变量表中变量的存储。最后,在G[]数组中,进行文法的定义。本实验为自动造表,故此处可修改文法,仅作细微改动即可。
int S[100];  //分析栈
int S_top = 0;  //分析栈栈顶
char T[100];  //符号栈 栈顶与分析栈总相同
string value[100];  //存储符号的属性
list L_sys;  //四元式
list sys;  //产生四元式的状态集
list V;  //变量表


int result_count = 0;
string G[11] = { "S->A", "A->V=E","E->E+T","E->E-T","E->T","T->T*F","T->T/F","T->F","F->(E)","F->i","V->i" };


程序结构描述:

整个程序较为庞大,自动构造文法分析所需的表,包括Vt/Vn/FIRST/FOLLOW/ACTION/ GOTO/变量表,之后进行SLR(1)分析,并且构造四元式。在这里进行详细说明:


完成整个程序的思路是:
->读取文件(获取输入的实验一运行结果、得到表达式)
->扫描文法(构建终结符号、非终结符号集、First/Follow集)
->造表(构造项目集族、构造ACTION/GOTO、设置四元式)
->SLR分析(判断是否可以被分析程序接受、生成四元式)


读取文件:readfile()将文件中的实验一的运行结果读入,整合为字符数组,准备好以待匹配,同前几次试验,在此不做赘述。


扫描文法:scan()将文法数组G[]中的string字符串进行扫描,构造终结符号集和非终结符号集;之后按照SLR(1)文法中FIRST集和FOLLOW集的构造方法进行这两个集合的构造。在构造FIRST集时,用到了find函数,用来不断地递归查找产生式首符号为非终结符号的产生式,以构造FIRST集;在构造FOLLOW集时,使用到了findVn函数,用来返回指定的非终结符对应的标号,以进行FOLLOW集的计算。同时,通过不断的循环、加入,当所有非终结符的FOLLOW集总大小不变时,跳出循环,构造完成。至此,造表前的准备工作全部完成,接下来进入造表阶段。


造表:table()完成整个项目集族的生成以及ACTION/GOTO的构造,以及在造表过程中对于四元式的标注,也是个人认为整个程序中最难的部分。
首先,进行初始设定:添加文法的起始符号对应的产生式,用以从初态进行迭代;之后将该产生式(点还处在最开始的部位tag=3, 尚未进入规约状态finish=0)加入第一个状态I0中,接下来进行一波循环操作:首先对于当前所有的项目集族进行闭包操作,该功能被封装在闭包函数closure()中(函数中对于每一个点操作的非终结符均进行闭包操作,加入该状态中,最终返回经过闭包操作的该状态);之后对于当前状态的每一条待移进的产生式分别进行移进操作,并添加为新的状态,等待循环到该状态时的闭包操作。在移进过程中,对于不是规约的(即尚可移进的)产生式,若点操作为非终结符,置GOTO(当前状态, 非终结符) = 新状态号;若为终结符,则置ACTION(当前状态,终结符号) = s+新状态号。若存在移进时的相同符号,则加入同一状态中,不再另设新状态。之后即为对于新状态的加入判断:若新状态的闭包操作closure()已经在已形成的项目集族中出现了,则不再添加这个新状态,并且修改对应的ACTION或者GOTO(一个pop()操作+一个push()操作);否则添加。对于需要规约的产生式,首先对其进行判断是否可以产生四元式:若可以,则进行记录,以便之后判断;否则不进行记录。至此,造表结束,接下来正式进入分析阶段。


SLR分析:SLR()完成最终整个SLR(1)文法的分析任务,也包括分析过程中完成的四元式构建。在分析过程起始时,首先将状态I0压入栈中,分析开始:若ACTION(栈顶,当前符号)不是acc(在程序中为r0),则开始循环:如果是err(在程序中使用0代替),报错;否则如果是sj,状态栈、符号栈、属性栈均压栈,读取下一个符号;如果是ri,则通过需要规约第i条产生式,对于三个栈,执行第i条产生式右部的符号数次pop()操作,同时更新属性栈,用以后续的四元式生成工作;在生成四元式时,首先判断正在规约的产生式是否可以产生四元式,同时确定四元式的op,其次判断两个参数(arg1,arg2)是否为变量or变量组成的表达式。如果是表达式,则查找之前的符号表,进行代替操作。若中间不报错而跳出循环,则成功匹配。至此,按照事先约定好的输出格式进行输出,分析任务完成。


程序测试:
测试用例
在本程序中,使用文件进行读取表达式的操作。测试输入串放在text.txt中,测试用例如下:


测试用例1:
12,
32,<=>
12,
23,<*>
28,<(>
12,
21,<+>
12,
29,<)>
33,
12,
测试用例2:
12,
32,<=>
28,<(>
12,
21,<+>
12,
29,<)>
33,
12,
23,<*>
28,<(>
12,
22,<->
12,
29,<)>

测试结果

测试1:
读入实验一结果:
12,
32,<=>
12,
23,<*>
28,<(>
12,
21,<+>
12,
29,<)>
33,
12,


输入串为:i=a*(b+c)/d#


终结符号集:=+-*/()i#
非终结符号集:SAVETF
FIRST
S     i
A     i
V     i
E     ( i
T     ( i
F     ( i
FOLLOW
S     #
A     #
V     =
E     # + - )
T     # + - * / )
F     # + - * / )
状态0:
  S->·A
  A->·V=E
  V->·i
状态1:
  S->A·
状态2:
  A->V·=E
状态3:
  V->i·
状态4:
  A->V=·E
  E->·E+T
  E->·E-T
  E->·T
  T->·T*F
  T->·T/F
  T->·F
  F->·(E)
  F->·i
状态5:
  A->V=E·
  E->E·+T
  E->E·-T
状态6:
  E->T·
  T->T·*F
  T->T·/F
状态7:
  T->F·
状态8:
  F->(·E)
  E->·E+T
  E->·E-T
  E->·T
  T->·T*F
  T->·T/F
  T->·F
  F->·(E)
  F->·i
状态9:
  F->i·
状态10:
  E->E+·T
  T->·T*F
  T->·T/F
  T->·F
  F->·(E)
  F->·i
状态11:
  E->E-·T
  T->·T*F
  T->·T/F
  T->·F
  F->·(E)
  F->·i
状态12:
  T->T*·F
  F->·(E)
  F->·i
状态13:
  T->T/·F
  F->·(E)
  F->·i
状态14:
  F->(E·)
  E->E·+T
  E->E·-T
状态15:
  E->E+T·
  T->T·*F
  T->T·/F
状态16:
  E->E-T·
  T->T·*F
  T->T·/F
状态17:
  T->T*F·
状态18:
  T->T/F·
状态19:
  F->(E)·
GOTO(0, A) = 1
GOTO(0, V) = 2
GOTO(4, E) = 5
GOTO(4, T) = 6
GOTO(4, F) = 7
GOTO(8, E) = 14
GOTO(8, T) = 6
GOTO(8, F) = 7
GOTO(10, T) = 15
GOTO(10, F) = 7
GOTO(11, T) = 16
GOTO(11, F) = 7
GOTO(12, F) = 17
GOTO(13, F) = 18
ACTION(0, i) = s3
ACTION(1, #) = r0
ACTION(2, =) = s4
ACTION(3, =) = r10
ACTION(4, () = s8
ACTION(4, i) = s9
ACTION(5, #) = r1
ACTION(5, +) = s10
ACTION(5, -) = s11
ACTION(6, #) = r4
ACTION(6, +) = r4
ACTION(6, -) = r4
ACTION(6, )) = r4
ACTION(6, *) = s12
ACTION(6, /) = s13
ACTION(7, #) = r7
ACTION(7, +) = r7
ACTION(7, -) = r7
ACTION(7, *) = r7
ACTION(7, /) = r7
ACTION(7, )) = r7
ACTION(8, () = s8
ACTION(8, i) = s9
ACTION(9, #) = r9
ACTION(9, +) = r9
ACTION(9, -) = r9
ACTION(9, *) = r9
ACTION(9, /) = r9
ACTION(9, )) = r9
ACTION(10, () = s8
ACTION(10, i) = s9
ACTION(11, () = s8
ACTION(11, i) = s9
ACTION(12, () = s8
ACTION(12, i) = s9
ACTION(13, () = s8
ACTION(13, i) = s9
ACTION(14, )) = s19
ACTION(14, +) = s10
ACTION(14, -) = s11
ACTION(15, #) = r2
ACTION(15, +) = r2
ACTION(15, -) = r2
ACTION(15, )) = r2
ACTION(15, *) = s12
ACTION(15, /) = s13
ACTION(16, #) = r3
ACTION(16, +) = r3
ACTION(16, -) = r3
ACTION(16, )) = r3
ACTION(16, *) = s12
ACTION(16, /) = s13
ACTION(17, #) = r5
ACTION(17, +) = r5
ACTION(17, -) = r5
ACTION(17, *) = r5
ACTION(17, /) = r5
ACTION(17, )) = r5
ACTION(18, #) = r6
ACTION(18, +) = r6
ACTION(18, -) = r6
ACTION(18, *) = r6
ACTION(18, /) = r6
ACTION(18, )) = r6
ACTION(19, #) = r8
ACTION(19, +) = r8
ACTION(19, -) = r8
ACTION(19, *) = r8
ACTION(19, /) = r8
ACTION(19, )) = r8


分析栈:(| |中的为非终结符号的属性)
0  3                                              i
0  2                                              V |i|
0  2  4                                           V |i| =
0  2  4  9                                        V |i| = a
0  2  4  7                                        V |i| = F |a|
0  2  4  6                                        V |i| = T |a|
0  2  4  6  12                                    V |i| = T |a| *
0  2  4  6  12 8                                  V |i| = T |a| * (
0  2  4  6  12 8  9                               V |i| = T |a| * ( b
0  2  4  6  12 8  7                               V |i| = T |a| * ( F |b|
0  2  4  6  12 8  6                               V |i| = T |a| * ( T |b|
0  2  4  6  12 8  14                              V |i| = T |a| * ( E |b|
0  2  4  6  12 8  14 10                           V |i| = T |a| * ( E |b| +
0  2  4  6  12 8  14 10 9                         V |i| = T |a| * ( E |b| + c
0  2  4  6  12 8  14 10 7                         V |i| = T |a| * ( E |b| + F |c|
0  2  4  6  12 8  14 10 15                        V |i| = T |a| * ( E |b| + T |c|
0  2  4  6  12 8  14                              V |i| = T |a| * ( E |b+c|
0  2  4  6  12 8  14 19                           V |i| = T |a| * ( E |b+c| )
0  2  4  6  12 17                                 V |i| = T |a| * F |b+c|
0  2  4  6                                        V |i| = T |a*b+c|
0  2  4  6  13                                    V |i| = T |a*b+c| /
0  2  4  6  13 9                                  V |i| = T |a*b+c| / d
0  2  4  6  13 18                                 V |i| = T |a*b+c| / F |d|
0  2  4  6                                        V |i| = T |a*b+c/d|
0  2  4  5                                        V |i| = E |a*b+c/d|
0  1                                              A |i=a*b+c/d|


匹配成功!


四元式:
(+,c,b,A)
(*,A,a,B)
(/,d,B,C)
请按任意键继续. . .
测试用例2:

读入实验一结果:
12,
32,<=>
28,<(>
12,
21,<+>
12,
29,<)>
33,
12,
23,<*>
28,<(>
12,
22,<->
12,
29,<)>




输入串为:r=(a+e)/b*(c-d)#


终结符号集:=+-*/()i#
非终结符号集:SAVETF
FIRST
S     i
A     i
V     i
E     ( i
T     ( i
F     ( i
FOLLOW
S     #
A     #
V     =
E     # + - )
T     # + - * / )
F     # + - * / )
状态0:
  S->·A
  A->·V=E
  V->·i
状态1:
  S->A·
状态2:
  A->V·=E
状态3:
  V->i·
状态4:
  A->V=·E
  E->·E+T
  E->·E-T
  E->·T
  T->·T*F
  T->·T/F
  T->·F
  F->·(E)
  F->·i
状态5:
  A->V=E·
  E->E·+T
  E->E·-T
状态6:
  E->T·
  T->T·*F
  T->T·/F
状态7:
  T->F·
状态8:
  F->(·E)
  E->·E+T
  E->·E-T
  E->·T
  T->·T*F
  T->·T/F
  T->·F
  F->·(E)
  F->·i
状态9:
  F->i·
状态10:
  E->E+·T
  T->·T*F
  T->·T/F
  T->·F
  F->·(E)
  F->·i
状态11:
  E->E-·T
  T->·T*F
  T->·T/F
  T->·F
  F->·(E)
  F->·i
状态12:
  T->T*·F
  F->·(E)
  F->·i
状态13:
  T->T/·F
  F->·(E)
  F->·i
状态14:
  F->(E·)
  E->E·+T
  E->E·-T
状态15:
  E->E+T·
  T->T·*F
  T->T·/F
状态16:
  E->E-T·
  T->T·*F
  T->T·/F
状态17:
  T->T*F·
状态18:
  T->T/F·
状态19:
  F->(E)·
GOTO(0, A) = 1
GOTO(0, V) = 2
GOTO(4, E) = 5
GOTO(4, T) = 6
GOTO(4, F) = 7
GOTO(8, E) = 14
GOTO(8, T) = 6
GOTO(8, F) = 7
GOTO(10, T) = 15
GOTO(10, F) = 7
GOTO(11, T) = 16
GOTO(11, F) = 7
GOTO(12, F) = 17
GOTO(13, F) = 18
ACTION(0, i) = s3
ACTION(1, #) = r0
ACTION(2, =) = s4
ACTION(3, =) = r10
ACTION(4, () = s8
ACTION(4, i) = s9
ACTION(5, #) = r1
ACTION(5, +) = s10
ACTION(5, -) = s11
ACTION(6, #) = r4
ACTION(6, +) = r4
ACTION(6, -) = r4
ACTION(6, )) = r4
ACTION(6, *) = s12
ACTION(6, /) = s13
ACTION(7, #) = r7
ACTION(7, +) = r7
ACTION(7, -) = r7
ACTION(7, *) = r7
ACTION(7, /) = r7
ACTION(7, )) = r7
ACTION(8, () = s8
ACTION(8, i) = s9
ACTION(9, #) = r9
ACTION(9, +) = r9
ACTION(9, -) = r9
ACTION(9, *) = r9
ACTION(9, /) = r9
ACTION(9, )) = r9
ACTION(10, () = s8
ACTION(10, i) = s9
ACTION(11, () = s8
ACTION(11, i) = s9
ACTION(12, () = s8
ACTION(12, i) = s9
ACTION(13, () = s8
ACTION(13, i) = s9
ACTION(14, )) = s19
ACTION(14, +) = s10
ACTION(14, -) = s11
ACTION(15, #) = r2
ACTION(15, +) = r2
ACTION(15, -) = r2
ACTION(15, )) = r2
ACTION(15, *) = s12
ACTION(15, /) = s13
ACTION(16, #) = r3
ACTION(16, +) = r3
ACTION(16, -) = r3
ACTION(16, )) = r3
ACTION(16, *) = s12
ACTION(16, /) = s13
ACTION(17, #) = r5
ACTION(17, +) = r5
ACTION(17, -) = r5
ACTION(17, *) = r5
ACTION(17, /) = r5
ACTION(17, )) = r5
ACTION(18, #) = r6
ACTION(18, +) = r6
ACTION(18, -) = r6
ACTION(18, *) = r6
ACTION(18, /) = r6
ACTION(18, )) = r6
ACTION(19, #) = r8
ACTION(19, +) = r8
ACTION(19, -) = r8
ACTION(19, *) = r8
ACTION(19, /) = r8
ACTION(19, )) = r8


分析栈:(| |中的为非终结符号的属性)
0  3                                              r
0  2                                              V |r|
0  2  4                                           V |r| =
0  2  4  8                                        V |r| = (
0  2  4  8  9                                     V |r| = ( a
0  2  4  8  7                                     V |r| = ( F |a|
0  2  4  8  6                                     V |r| = ( T |a|
0  2  4  8  14                                    V |r| = ( E |a|
0  2  4  8  14 10                                 V |r| = ( E |a| +
0  2  4  8  14 10 9                               V |r| = ( E |a| + e
0  2  4  8  14 10 7                               V |r| = ( E |a| + F |e|
0  2  4  8  14 10 15                              V |r| = ( E |a| + T |e|
0  2  4  8  14                                    V |r| = ( E |a+e|
0  2  4  8  14 19                                 V |r| = ( E |a+e| )
0  2  4  7                                        V |r| = F |a+e|
0  2  4  6                                        V |r| = T |a+e|
0  2  4  6  13                                    V |r| = T |a+e| /
0  2  4  6  13 9                                  V |r| = T |a+e| / b
0  2  4  6  13 18                                 V |r| = T |a+e| / F |b|
0  2  4  6                                        V |r| = T |a+e/b|
0  2  4  6  12                                    V |r| = T |a+e/b| *
0  2  4  6  12 8                                  V |r| = T |a+e/b| * (
0  2  4  6  12 8  9                               V |r| = T |a+e/b| * ( c
0  2  4  6  12 8  7                               V |r| = T |a+e/b| * ( F |c|
0  2  4  6  12 8  6                               V |r| = T |a+e/b| * ( T |c|
0  2  4  6  12 8  14                              V |r| = T |a+e/b| * ( E |c|
0  2  4  6  12 8  14 11                           V |r| = T |a+e/b| * ( E |c| -
0  2  4  6  12 8  14 11 9                         V |r| = T |a+e/b| * ( E |c| - d
0  2  4  6  12 8  14 11 7                         V |r| = T |a+e/b| * ( E |c| - F |d|
0  2  4  6  12 8  14 11 16                        V |r| = T |a+e/b| * ( E |c| - T |d|
0  2  4  6  12 8  14                              V |r| = T |a+e/b| * ( E |c-d|
0  2  4  6  12 8  14 19                           V |r| = T |a+e/b| * ( E |c-d| )
0  2  4  6  12 17                                 V |r| = T |a+e/b| * F |c-d|
0  2  4  6                                        V |r| = T |a+e/b*c-d|
0  2  4  5                                        V |r| = E |a+e/b*c-d|
0  1                                              A |r=a+e/b*c-d|


匹配成功!


四元式:
(+,e,a,A)
(/,b,A,B)
(-,d,c,C)
(*,C,B,D)
请按任意键继续. . .

学习总结:
起初,只是想动手做一个手动造表的SLR程序。后来在实际操作的过程中,听说这次实验比较难,涉及到分析过程、还包括四元式,就有些觉得不是那么容易。不过,后来还是铁了心,想完成一个自动造表的程序,从开始到结尾没有人为设定的表和其他设置。刚开始做的时候还是比较不太舒服,毕竟规则还没有掌握清楚,开始上手做时还是不太顺利的。到后来慢慢了解整个算法的原理,再到后来不去翻书也大概明白整个算法是怎么回事,主动去迎接一个不是那么轻松就可以完成的实验...个人感觉收获还是很大的。目前实验的不足是部分输出还不是很规范(不包括在字符界面还是对齐的栈到了word里面不知道为什么就不齐了),还有提升空间。


附:完整实现代码(详见.cpp文件)
/*
完成以下描述赋值语句 SLR(1)文法语法制导生成中间代码四元式的过程。
G[A]:
A→V=E
E→E+T∣E-T∣T
T→T*F∣T/F∣F
F→(E)∣i
V→i
[设计说明] 终结符号 i 为用户定义的简单变量, 即标识符的定义。
[设计要求]
(1)构造文法的 SLR(1)分析表,设计语法制导翻译过程,给出每一产生式对应的语义动作;
(2)设计中间代码四元式的结构;
(3)输入串应是词法分析的输出二元式序列,即某赋值语句“专题 1”的输出结果,
输出为赋值语句的四元式序列中间文件;
(4)设计两个测试用例(尽可能完备),并给出程序执行结果四元式序列。
*/
#include "stdafx.h"
#include 
#include 
#include 
#include 


using namespace std;


typedef struct
{
	int finish = 0;  //是否结束
	int tag = 3;  //当前圆点的位置
	string str;
}sentence;


typedef struct
{
	int I;  //当前状态
	char Vt;  //终结符号
	char tag;  //r||s
	int action;  //动作
}act;


typedef struct
{
	int I;  //当前状态
	char Vn;  //非终结符
	int next_I;  //转移状态
}go;


typedef struct
{
	int number;  //编号
	list l;
}I;  //状态


typedef struct
{
	char op;
	char arg1;
	char arg2;
	char result;
}siyuanshi;


typedef struct
{
	char name;
	string value;  //place
}var;  //变量


list DFA;  //状态集
list *First;  //FIRST集
list *Follow;  //FOLLOW集
list ACTION;  //ACTION[i][j]
list GOTO;  //GO[i][j]
list Vt;  //终结符号集
list Vn;  //非终结符号集


char input[100];// = { 'i','=','a','*','(','b','+','c',')','/','d','#' };


void readfile()
{
	cout << "读入实验一结果:" << endl;
	char read[10];  //读取文件
	FILE *fp;
	fp = fopen("text.txt", "r+");
	int num = 0;
	while (fgets(read, 10, fp) != NULL)
	{
		int i;
		cout< L_sys;  //四元式
list sys;  //产生四元式的状态集
list V;  //变量表


int result_count = 0;
string G[11] = { "S->A", "A->V=E","E->E+T","E->E-T","E->T","T->T*F","T->T/F","T->F","F->(E)","F->i","V->i" };


act getACTION(int i,char b)
{
	char c = b;
	if (b >= 'a'&&b <= 'z')
		b = 'i';
	list::iterator it;
	for (it = ACTION.begin(); it != ACTION.end(); it++)
	{
		if (it->I == i &&it->Vt == b)
		{
			return *it;
		}
	}
	return {0,0,0,0};  //ERROR
}


int getGOTO(int i, char b)
{
	list::iterator it;
	for (it = GOTO.begin(); it != GOTO.end(); it++)
	{
		if (it->I == i &&it->Vn == b)
			return  it->next_I;
	}
	return -1;  //ERROR
}


char newTemp()
{
	char c = 'A';
	result_count++;
	return c + result_count-1;
}


void SLR()
{
	int V_num = 0;  //符号表
	int index = 0;
	S[0] = 0;  //init
	cout << "分析栈:(| |中的为非终结符号的属性)" << endl;
	while (getACTION(S[S_top],input[index]).tag != 'r' || getACTION(S[S_top], input[index]).action != 0)  //acc
	{
	/*	if (input[index] >= 'a'&&input[index] <= 'z')
		{
			string str = "i";
			str += to_string(V_num);
			V_num++;
			V.push_back({ str,input[index] });
		}
		for (list::iterator v = V.begin(); v != V.end(); v++)
		{
			cout << v->name << " " << v->value << endl;
		}
	*/	
		if (getACTION(S[S_top], input[index]).tag == 0)  //ERROR
		{
			cout<<"error!"<::iterator v = V.begin(); v != V.end(); v++)
						{
							if (v->value == value[S_top])
							{
								arg1 = v->name;
								break;
							}
						}
					}
				if (j == 2)
					if (value[S_top].length() == 1)
						arg2 = value[S_top][0];
					else
						for (list::iterator v = V.begin(); v != V.end(); v++)
						{
							if (v->value == value[S_top])
							{
								arg2 = v->name;
								break;
							}
						}
				S[S_top] = -1;
				T[S_top] = 0;
				value[S_top] = "";
				S_top--;
			}
			for (list::iterator ii = sys.begin(); ii != sys.end(); ii++)  //生成四元式
				if (i == *ii)
				{
					result = newTemp();
					V.push_back({ result,str });
					L_sys.push_back({ G[i][4],arg1,arg2,result });
					break;
				}
			//push
			S[S_top + 1] = getGOTO(S[S_top], G[i][0]);
			T[S_top + 1] = G[i][0];
			value[S_top + 1] = str;  //属性传递
			S_top++;
		}
		for (int tt = 0; tt <= 15; tt++)
		{
			if (tt <= S_top)
				if (S[tt] >= 10)
					cout << S[tt] << " ";
				else
					cout << S[tt] << "  ";
			else
				cout << "   ";
		}


		for (int tt = 0; tt <= S_top; tt++)
		{
			if (tt <= S_top)
			{
				cout << T[tt]<<" ";
				if(isupper(T[tt]))
					cout << "|" << value[tt] << "| ";
			}
			else
				cout << "  ";
		}
		cout << endl;
	}
	cout << endl << "匹配成功!" << endl;
	cout << endl << "四元式:" << endl;
	for (list::iterator s = L_sys.begin(); s != L_sys.end(); s++)
	{
		cout << '(' << s->op << "," << s->arg1 << "," << s->arg2 << ',' << s->result << ')' << endl;
	}
}


void print(sentence s)
{
	int r;
	cout << "  ";
	for (r = 0; r < s.str.length(); r++)
		if (r == s.tag)
			cout << "·" << s.str[r];
		else
			cout << s.str[r];
	if (r == s.tag)
		cout << "·";
	cout << endl;
}




void find(char ch, int tag_Vn)
{
	for (int qq = 0; qq < 11; qq++)
	{
		if (ch == G[qq][0])
		{
			if (G[qq][3] >= 'A'&&G[qq][3] <= 'Z')
				if (G[qq][3] == ch)  //避免死循环重复查找
					;
				else
					find(G[qq][3], tag_Vn);
			else
			{
				int tag = 0;
				for (list::iterator i = First[tag_Vn].begin(); i != First[tag_Vn].end(); i++)
				{
					if (*i == G[qq][3])
					{
						tag = 1;
						break;
					}
				}
				if (tag == 0)
					First[tag_Vn].push_back(G[qq][3]);
			}
		}
	}
}


int findVn(char c)
{
	int tag = -1;
	for (list::iterator i = Vn.begin(); i != Vn.end(); i++)
	{
		tag++;
		if (c == *i)
			return tag;
	}
	return -1;
}




void scan()  //构造符号集
{
	for (int i = 0; i < 11; i++)//文法长度
	{
		for (int j = 0; j < G[i].length(); j++)
		{
			if (j == 1 || j == 2)
				continue;
			if (isupper(G[i][j]))
			{
				if (find(Vn.begin(), Vn.end(), G[i][j]) == Vn.end())
					Vn.push_back(G[i][j]);
			}
			else
			{
				if (find(Vt.begin(), Vt.end(), G[i][j]) == Vt.end())
					Vt.push_back(G[i][j]);
			}
		}
	}
	Vt.push_back('#');




	First = new list[Vn.size()];
	int tag_Vn = -1;
	for (list::iterator ch = Vn.begin(); ch != Vn.end(); ch++)
	{
		tag_Vn++;
		for (int qq = 0; qq < 11; qq++)
		{
			if (*ch == G[qq][0])
			{
				if (G[qq][3] >= 'A'&&G[qq][3] <= 'Z')
				{
					find(G[qq][3], tag_Vn);
				}
				else
				{
					First[tag_Vn].push_back(G[qq][3]);
				}
			}
		}
	}




	Follow = new list[Vn.size()];
	Follow[0].push_back('#');


	int follow_sum = 0;  //follow集数量总和
	int previous_sum = -1;  //之前的总和
	while (follow_sum != previous_sum)
	{
		for (int i = 0; i < 11; i++)
		{
			for (int j = 3; j < G[i].length() - 1; j++)
			{
				if (isupper(G[i][j]))
					if (!isupper(G[i][j + 1]))  //是终结符号
					{
						int tag = 0;
						for (list::iterator ii = Follow[findVn(G[i][j])].begin(); ii != Follow[findVn(G[i][j])].end(); ii++)
						{
							if (*ii == G[i][j + 1])
							{
								tag = 1;
								break;
							}
						}
						if (tag == 0)
							Follow[findVn(G[i][j])].push_back(G[i][j + 1]);
					}
					else  //是非终结符号
					{
						for (list::iterator ii = Follow[findVn(G[i][j + 1])].begin(); ii != Follow[findVn(G[i][j + 1])].end(); ii++)
						{
							if (find(Follow[findVn(G[i][j + 1])].begin(), Follow[findVn(G[i][j + 1])].end(), *ii) == Follow[findVn(G[i][j + 1])].end())  //不重复
								Follow[findVn(G[i][j])].push_back(*ii);
						}
					}
			}
			if (isupper(G[i][G[i].length() - 1]))
				for (list::iterator ii = Follow[findVn(G[i][0])].begin(); ii != Follow[findVn(G[i][0])].end(); ii++)
				{
					if (find(Follow[findVn(G[i][G[i].length() - 1])].begin(), Follow[findVn(G[i][G[i].length() - 1])].end(), *ii) == Follow[findVn(G[i][G[i].length() - 1])].end())  //不重复
						Follow[findVn(G[i][G[i].length() - 1])].push_back(*ii);
				}
		}
		previous_sum = follow_sum;
		follow_sum = 0;
		for (int ii = 0; ii < Vn.size(); ii++)
		{
			follow_sum += Follow[ii].size();
		}
	}
	list::iterator iter;
	cout<<"终结符号集:";
	for (iter = Vt.begin(); iter != Vt.end(); iter++)
	{
	    cout<<*iter;
	}
	cout << endl;
	cout<<"非终结符号集:";
	for (iter = Vn.begin(); iter != Vn.end(); iter++)
	{
		cout << *iter;
	}
	cout << endl;
	int pp;
	cout << "FIRST" << endl;
	for (pp = 0, iter = Vn.begin(); pp < Vn.size(); pp++, iter++)
	{
		cout << *iter << "     ";
		for (list::iterator ch = First[pp].begin(); ch != First[pp].end(); ch++)
		{
			cout << *ch << " ";
		}
		cout << endl;
	}
	cout <<"FOLLOW"<< endl;
	for (pp = 0, iter = Vn.begin(); pp < Vn.size(); pp++, iter++)
	{
		cout << *iter << "     ";
		for (list::iterator ch = Follow[pp].begin(); ch != Follow[pp].end(); ch++)
		{
			cout << *ch << " ";
		}
		cout << endl;
	}


}




I closure(I &dfa)
{
	list::iterator iter;
	for (iter = dfa.l.begin(); iter != dfa.l.end(); iter++)
	{
		if ((iter->tag <= iter->str.length()))
			if ((iter->str[iter->tag] >= 'A'&&iter->str[iter->tag] <= 'Z'))
			{
				for (int tt = 0; tt < 11; tt++)  //查找对应的产生式
				{
					if (iter->str[iter->tag] == G[tt][0])
					{
						int q = 0;
						list::iterator it;
						sentence x;
						x.str = G[tt];
						for (it = dfa.l.begin(); it != dfa.l.end(); it++)
						{
							if ((it->str == x.str) && (it->tag == x.tag))
							{
								q = 1;
								break;
							}
						}
						if (q == 0)
						{
							dfa.l.push_back(x);
						}
					}
				}
			}
	}
	return dfa;
}
int compare(I a, I b) //是否相等
{
	
	if (a.l.size() != b.l.size())
		return 1;
	else
	{
		for (list::iterator iii = a.l.begin(), jjj = b.l.begin(); iii != a.l.end() || jjj != b.l.end(); iii++, jjj++)
			if (iii->str != jjj->str || iii->tag != jjj->tag)  //判断是否相等
			{
				return 1;
			}
	}
	return 0;
}


void table() 
{
	int num = 0;
	sentence first;  //起始符号
	first.str = G[0];
	
	I L;
	L.number = 0;
	L.l.push_back(first);
	DFA.push_back(L);


	list::iterator dfa;
	for (dfa = DFA.begin(); dfa != DFA.end(); dfa++)
	{
		list::iterator iter;
		closure(*dfa);
		for (iter = dfa->l.begin(); iter != dfa->l.end(); iter++)  //对状态中的每一产生式右部进行处理
			if (iter->finish == 0)
			{
				I C;  //新状态
				C.number = DFA.size();
				if (iter->tag < iter->str.length())  //尚未完成
				{
					sentence s;
					s.str = iter->str;
					if (iter->str[iter->tag] >= 'A'&&iter->str[iter->tag] <= 'Z')
					{
						GOTO.push_back({ dfa->number,iter->str[iter->tag],C.number });
					}
					else 
					{
						ACTION.push_back({ dfa->number,iter->str[iter->tag],'s',C.number });
					}
					s.tag = iter->tag + 1;
					iter->finish = 1;
					C.l.push_back(s);
					list::iterator i;
					for (i = iter, i++; i != dfa->l.end(); i++)
						if (i->str[i->tag] == iter->str[iter->tag])
						{
							s.str = i->str;
							s.tag = i->tag + 1;
							i->finish = 1;
							C.l.push_back(s);
						}


					int judge = 0, count = 0;
					for (list::iterator ii = DFA.begin(); ii != DFA.end(); ii++, count++)  //判断是否有重复
					{
						judge = compare(*ii, closure(C));  //修改C
						if (judge == 0)
							break;
					}
					if (judge == 0)
					{
						if (iter->str[iter->tag] >= 'A'&&iter->str[iter->tag] <= 'Z')
						{
							GOTO.pop_back();
							GOTO.push_back({ dfa->number,iter->str[iter->tag], count });
						}
						else
						{
							ACTION.pop_back();
							ACTION.push_back({dfa->number,iter->str[iter->tag],'s',count});
						}
					}
					else
						DFA.push_back(C);
				}
				else  //已经完成
				{
					int cc = 0, tt;
					for (tt = 0; tt < 11; tt++)
					{
						if (iter->str == G[tt])
							break;
					}
					for (list::iterator c = Vn.begin(); c != Vn.end(); c++, cc++)
						if (*c == iter->str[0])
							break;
					for (list::iterator c = Follow[cc].begin(); c != Follow[cc].end(); c++)
					{
						ACTION.push_back({ dfa->number,*c,'r',tt });  //对应的第j条产生式
						for (int ss = 3; ss < G[tt].length(); ss++)  //查找四元式对应的产生式
							if ( G[tt][ss] == '+' || G[tt][ss] == '-' || G[tt][ss] == '*' || G[tt][ss] == '/')
							{
								sys.push_back(tt);
							}
					}
				}
			}
	}


	num = 0;
	for (dfa = DFA.begin(); dfa != DFA.end(); dfa++)
	{
		cout << "状态" << num++ << ":" << endl;
		for (list::iterator iii = dfa->l.begin(); iii != dfa->l.end(); iii++)
		{
			print(*iii);
		}
	}
	for (list::iterator g = GOTO.begin(); g != GOTO.end(); g++)
	{
		cout <<"GOTO("<< g->I << ", " << g->Vn << ") = " << g->next_I <::iterator a = ACTION.begin(); a != ACTION.end(); a++)
	{
		cout << "ACTION(" << a->I << ", " << a->Vt << ") = " << a->tag << a->action << endl;
	}
	cout << endl;
}




int main()
{
	readfile();
	scan();
	table();
	SLR();
    return 0;
}


你可能感兴趣的:(编译原理)