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;
}