哈尔滨理工大学
软件与微电子学院
实 验 报 告
(2017-2018第二学期)
课程名称: 编译原理
班 级: 软件16-1班
学 号: 1614010102
姓 名: 曹妍
实验名称 姓 名 实验一、算符优先分析表的构造程序 曹妍 学 号 1614010102 专 业 班 级 软件工程 软件16-1班 一、实验目的:
通过设计编制调试构造FIRSTVT集、LASTVT集和构造算符优先表,了解构造算符优先分析表的步骤,对文法的要求,生成算符优先关系表的算法。
二、实验内容:
1.编写算符优先分析表的构造程序,求出给定的算符优先文法中的非终结符的FirstVT集合和LastVT集合。
2.构造算符优先表。
三、实验设备及软件环境:
PC机,主机操作系统为windows;C编译器等软件
四、实验过程及结果:
在存放文法的文件in.txt内输入待判断文法产生式(文件已输入教材116页文法),格式E->a|S,注意左部和右部之间是“->”,每个产生式一行,ENTER键换行。文法结束再输入一行G->#E#。
1.先做文法判断,即可判断文法情况。
2.若是算符优先文法,则在优先表栏显示优先表。
实验样例:图中给出了终结符号表,非终结符号表,计算FirstVT和LastVT集合,并给出 了算符优先关系矩阵。
代码和实验结果分析:
#include
char data[20][20]; //算符优先关系 char s[100]; //模拟符号栈s char lable[20]; //文法终极符集 char input[100]; //文法输入符号串 char string[20][10]; //用于输入串的分析 int k; char a; int j; char q;
int r; //文法规则个数
int r1; //转化后文法规则个数 char st[10][30]; //用来存储文法规则 char first[10][10]; //文法非终结符FIRSTVT集 char last[10][10]; //文法非终结符LASTVT集
int fflag[10]= {0}; //标志第i个非终结符的FIRSTVT集是否已求出
int lflag[10]= {0}; //标志第i个非终结符的LASTVT集是否已求出
int deal(); //对输入串的分析 int zhongjie(char c); //判断字符c是否是终极符
int xiabiao(char c); //求字符c在算符优先关系表中的下标 void out(int j,int k,char *s); //打印s栈
void firstvt(char c); //求非终结符c的FIRSTVT集 void lastvt(char c); //求非终结符c的LASTVT集 void table(); //创建文法优先关系表 int main() {
int i,j,k=0;
printf(\请输入文法规则数:\ scanf(\
printf(\请输入文法规则:\\n\ for(i=0; i scanf(\ //存储文法规则,初始化FIRSTVT集和LASTVT集 first[i][0]=0; /*first[i][0]和last[i][0]分别表示st[i][0]非终极符的FIRSTVT集和LASTVT集中元素的个数*/ last[i][0]=0; } for(i=0; i for(j=0; st[i][j]!='\\0'; j++) { if(st[i][0]<'A'||st[i][0]>'Z') { printf(\不是算符文法!\\n\ exit(-1); } if(st[i][j]>='A'&&st[i][j]<='Z') { if(st[i][j+1]>='A'&&st[i][j+1]<='Z') { printf(\不是算符文法!\\n\ exit(-1); } } } } for(i=0; i for(j=0; st[i][j]!='\\0'; j++) { if((st[i][j]<'A'||st[i][j]>'Z')&&st[i][j]!='-'&&st[i][j]!='>'&&st[i][j]!='|') lable[k++]=st[i][j]; } } lable[k]='#'; lable[k+1]='\\0'; table(); printf(\每个非终结符的FIRSTVT集为:\\n\ //输出每个非终结符的FIRSTVT集 for(i=0; i printf(\ for(j=0; j printf(\ } printf(\ } printf(\每个非终结符的LASTVT集为:\\n\ LASTVT集 for(i=0; i printf(\ for(j=0; j printf(\ } printf(\ } printf(\算符优先分析表如下:\\n\ for(i=0; lable[i]!='\\0'; i++) printf(\ printf(\ for(i=0; i printf(\ //输出每个非终结符的