您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 酒店餐饮 > 编译原理实验-查填符号表(含源代码和运行结果)
《编译原理》实验报告实验1查填符号表姓名学号班级计科1001班时间:2012/3/22地点:文波同组人:无指导教师:朱少林实验目的1、运用所学知识,选择语言、选择算法(数据结构),编程实现符号表管理程序。2、熟悉编译过程,训练编写程序的能力,为后续实验积累经验。实验内容1、运用所学知识,编程实现符号表管理程序。读出源程序中与C语言词法规定相一致的标识符,并在符号表中进行查找,若存在则输出该标识符及其编号和位置;否则将其填入符号表,并分配编号,确定位置,输出该标识符。2、输出标识符表。实验环境软件:VC++6.0实验前准备1、方案设计:①准备模拟数据:由于是识别符合c语言规定的标识符,故本实验中使用“测试文件.c”②写出c语言标识符的正规式定义:letter_→A|B|C|…Z|a|b|…z|_digit→0|1|…9id→letter_(letter_|digit)*③画出不确定的有限自动机不确定的有限自动机如下:进行化简:A={1}B={2,3,4,5,9}C={3,4,5,6,8,9}D={3,4,5,7,8,9}状态转换表如下:状态letter_digitABBCDCCDDCD进行化简:{A}{B,C,D}化简后的确定有限自动机如下:④程序思想:该实验重点是构造识别标识符的函数。程序中,使用的数据结构如下:structrecord{charname[20];};typedefstructrecordRECORD;record是用来记录标识符的名字,并且规定标识符的长度最大为20structinfor//记录符号表的相关信息{structrecord*head;intlength;//记录符号表的长度};typedefstructinforINFOR;infor是用来指向record结构体的指针和符号表的长度,这个结构体主要是用于比较标识符并将识别到的标识符写入分析结果文件中即本实验中的“search_table”函数,该函数并没有直接把标识符写到文件,而是在该函数之外,新建一个文件用来放符号表,然在后来打印符号表的同时把打印的结果写该文件中去。该程序中的“search_table”函数判断是否为新的标识符的方法就是把识别的一个标识符与已经识别的一一比较看是否相同,如不相同则表长度加1,并将该标识符填入表中while(ji&&strcmp(teststring,point[j].name)){j++;}//与已有的标识符一一比较if(j==i)//说明是新的标识符{strcpy(point[j].name,teststring);//point[j].line=j;p-length++;}2、程序设计#includestdio.h#includestdlib.h#includestring.hstructrecord{charname[20];};typedefstructrecordRECORD;structinfor//记录符号表的相关信息{structrecord*head;intlength;//记录符号表的长度};typedefstructinforINFOR;voidsearch_table(char*teststring,INFOR*p,FILE*f)//查填符号表函数,p为指向结构体的指针{inti=p-length;intj=0;RECORD*point;point=p-head;while(ji&&strcmp(teststring,point[j].name)){j++;}//与已有的标识符一一比较if(j==i)//说明是新的标识符{strcpy(point[j].name,teststring);//point[j].line=j;p-length++;}printf(标识符%s在符号表的第%d行\n,teststring,j+1);fprintf(f,%s\t%5d\n,teststring,j+1);//将新的标识符写入文件分析结果文件f中return;}voidmain(){charreadchar;//从文件中读到的字符charteststr[20];//存放标识符charlinkstr[2]={0};//用于把字符readchar连接到teststrFILE*fp;fp=fopen(测试文件.c,r);if(fp==NULL){printf(打开文件失败!);exit(0);}//打开测试文件fpFILE*result;result=fopen(结果.txt,w+);//新建打开一个存放分析结果的文件result//fclose(result);这个命令使下面调用的search_table函数不能将分析结果写入“结果.txt”//,因为search_table函数函数中没有打开“结果.txt”命令INFORinformation;//用于指向符号表RECORDmark[300];//定义符号表最多可以有300个符号information.head=mark;information.length=0;readchar=fgetc(fp);//charhistory=readchar;利用这个记录读取的上一个字符,判断是否是数字while(readchar!=EOF){teststr[0]=0;if(readchar='z'&&readchar='a'||readchar='A'&&readchar='Z'||readchar=='_')//字母数字下划线开头,如果这个满足则下面的也一定满足{while(readchar='z'&&readchar='a'||readchar='A'&&readchar='Z'||readchar=='_'||readchar='0'&&readchar='9'){linkstr[0]=readchar;strcat(teststr,linkstr);//会自动添加‘\0’//if(history'9'&&history'0')readchar=fgetc(fp);}if(strlen(teststr)!=0){search_table(teststr,&information,result);//将结果写入结果.txt}}//这个循环结束后就读入一个标识符readchar=fgetc(fp);}fclose(fp);fclose(result);FILE*table=fopen(符号表.txt,w+);//新建符号表.txt文件if(table==NULL){printf(文件打开失败!);exit(0);}inti=0;//printf(行数\t);//printf(标识符\n);printf(************************************\n);printf(以下是符号表的内容\n);printf(行数\t\t\t标识符\n);while(iinformation.length){printf(%3d\t\t\t%s\n,i+1,mark[i].name);fwrite(&information.head[i],strlen(mark[i].name),1,table);fprintf(table,%4d\n,i+1);//向符号表中写入数据i++;}fclose(table);}实验步骤1、建立简单的符号表,可以只包含标识符和编号;2、编写单词解析子程序,从源程序中分离出单词;3、编写查找标识符的子程序(应考虑查找算法),插入新的标识符;4、程序调试,输出标识符表。实验结果及其分析:分析后输出的分析文件是“结果.txt”内容如下:include1stdio2h3int4_qq5int4temp6char7temp_s8int4search9char7str10char7c11void12main13char7str10c11int4m14i15printf16please17input18a19string20gets21str10puts22please17input18the23char7you24search9c11getchar25m14search9str10c11if26m14printf16can27not28find29else30printf16the23c11you24search9is31d32n33m14int4search9char7str10char7c11int4i15for34i15str10i15i15if26str10i15c11return35i15return35存放符号表的文件“符号表.txt”内容如下:include1stdio2h3int4_qq5temp6char7temp_s8search9str10c11void12main13m14i15printf16please17input18a19string20gets21puts22the23you24getchar25if26can27not28find29else30is31d32n33for34return35使用的模拟数据“测试文件.c”如下:#includestdio.hint_qq;int3temp;chartemp_s;intsearch(charstr[80],charc);voidmain(){charstr[80],c;intm,i;printf(pleaseinputastring:);gets(str);puts(pleaseinputthecharyousearch);c=getchar();m=search(str,c);if(m==-1)printf(cannotfind);elseprintf(thecyousearchis%d\n,m);}intsearch(charstr[80],charc){inti;for(i=0;str[i]!='\0';i++){if(str[i]==c){return(i);}}return-1;}分析:实验过程中最大的难题是文件的操作,因为之前关于文件的操作课程没有讲,再加上很久没写代码的原因,就先学了下文件操作,实验过程中最开始“结果.txt”总是空,后来知道原来是我在创建了该文件后就关闭了,在没有打开的情况下不能进行写入结果的操作;还有就是刚开始的“符号表.txt”每个符号后面都有不同数目的“烫”,经分析知道这种情况下每个标识符都是强制的长度一致,都是20(定义的标识符最大长度是20),这是因为向文件中写入数据时:fwrite(&information.head[i],strlen(mark[i].name),1,table);我把每次写入的数据块长度设为了sizeof(record),而该结果是20,所以导致每个标识符长度是20.不过该实验还有一个地方需要改进,因为对于“23aa”这样的字符串“aa”按照规定应该不是一个标识符,而在这个试验中却也把“aa”识别为了一个标识符,本来想用一个char型history来记录上个读入字符来判断识别的字符串是不是以数字开头的某字符串的后部分,但是没成功,时间关系,我再思考下如何实现该功能。
本文标题:编译原理实验-查填符号表(含源代码和运行结果)
链接地址:https://www.777doc.com/doc-6617652 .html