编译原理实验报告学号:姓名:提交日期:成绩:实验编号实验二实验名称词法分析程序的设计与实现一.实验二:词法分析程序的设计与实现【实验目的和要求】设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解。【实验描述】通过对PL/0词法分析程序(GETSYM)的分析,并在此基础上按照附录A中给出的PL/0语言的语法描述,编写一个PL/0语言的词法分析程序。此程序应具有如下功能:输入为字符串(待进行词法分析的源程序),输出为单词串,即由(单词、类别)所组成的二元组序列。有一定检查错误的能力,例如发现2A这类不能作为单词的字符串。【主要变量名说明】char*key[8]={if,else,for,while,do,return,break,continue};确定关键字char*border[6]={,,;,{,},(,)};确定界符char*arithmetic[4]={+,-,*,/};确定算术运算符char*relation[6]={,=,=,,=,};确定关系运算符【程序清单】#includestdio.h#includectype.h#includestdlib.h#includestring.h#defineNULL0#includeiostreamusingnamespacestd;FILE*fp;charcbuffer;char*key[8]={if,else,for,while,do,return,break,continue};char*border[6]={,,;,{,},(,)};char*arithmetic[4]={+,-,*,/};char*relation[6]={,=,=,,=,};char*consts[20];char*label[20];intconstnum=0,labelnum=0;/////////////////////////////////////////////////////////////////////////////////////////////////////intsearch(charsearchchar[],intwordtype){inti=0;switch(wordtype){case1:{for(i=0;i=7;i++){if(strcmp(key[i],searchchar)==0)return(i+1);}return0;}case2:{for(i=0;i=5;i++){if(strcmp(border[i],searchchar)==0)return(i+1);}return(0);}case3:{for(i=0;i=3;i++){if(strcmp(arithmetic[i],searchchar)==0){return(i+1);}}return(0);}case4:{for(i=0;i=5;i++){if(strcmp(relation[i],searchchar)==0){return(i+1);}}return(0);}case5:{for(i=0;i=constnum;i++){if(i!=constnum){if(strcmp(consts[i],searchchar)==0)return(i+1);}}consts[i-1]=(char*)malloc(sizeof(searchchar));strcpy(consts[i-1],searchchar);constnum++;return(i);}case6:{for(i=0;i=labelnum;i++){if(i!=labelnum){if(strcmp(label[i],searchchar)==0)return(i+1);}}label[i-1]=(char*)malloc(sizeof(searchchar));strcpy(label[i-1],searchchar);labelnum++;return(i);}default:return0;}}/////////////////////////////////////////////////////////////////////////////////////////////////////charalphaprocess(charbuffer){intatype;inti=-1;charalphatp[20];while((isalpha(buffer))||(isdigit(buffer))){alphatp[++i]=buffer;buffer=fgetc(fp);}alphatp[i+1]='\0';if(atype=search(alphatp,1)){printf(%8s(1,%d)\n,alphatp,atype-1);}else{atype=search(alphatp,6);printf(%8s(6,%d)\n,alphatp,atype-1);}return(buffer);}/////////////////////////////////////////////////////////////////////////////////////////////////////chardigitprocess(charbuffer){inti=-1;chardigittp[20];intdtype;while((isdigit(buffer))){digittp[++i]=buffer;buffer=fgetc(fp);}digittp[i+1]='\0';dtype=search(digittp,5);printf(%8s(5,%d)\n,digittp,dtype-1);return(buffer);}/////////////////////////////////////////////////////////////////////////////////////////////////////charotherprocess(charbuffer){inti=-1;charothertp[20];intotype,otypetp;othertp[0]=buffer;othertp[1]='\0';if(otype=search(othertp,3)){printf(%8s(3,%d)\n,othertp,otype-1);buffer=fgetc(fp);gotoout;}if(otype=search(othertp,4)){buffer=fgetc(fp);othertp[1]=buffer;othertp[2]='\0';if(otypetp=search(othertp,4)){buffer=fgetc(fp);}else{othertp[1]='\0';}printf(%8s(4,%d)\n,othertp,otype-1);gotoout;}if(buffer==':'){buffer=fgetc(fp);if(buffer=='=')printf(%8s(2,2)\n,:=);buffer=fgetc(fp);gotoout;}else{if(otype=search(othertp,2)){printf(%8s(2,%d)\n,othertp,otype-1);buffer=fgetc(fp);gotoout;}}if((buffer!='\n')&&(buffer!='')&&(buffer!='\t')){printf(%8cerror,notaword\n,buffer);}buffer=fgetc(fp);out:return(buffer);}/////////////////////////////////////////////////////////////////////////////////////////////////////voidmain(){inti;for(i=0;i=20;i++){label[i]=NULL;consts[i]=NULL;}if((fp=fopen(example.c,r))==NULL)printf(error!\n);else{cbuffer=fgetc(fp);while(cbuffer!=EOF){if(isalpha(cbuffer))cbuffer=alphaprocess(cbuffer);elseif(isdigit(cbuffer))cbuffer=digitprocess(cbuffer);elsecbuffer=otherprocess(cbuffer);}printf(over!\n);system(pause);}}///////////////////////////////////////////////////////////////////////////////////////////////////////源程序over///////////////////////////////////////////////////////////////////////////////////////////////////////实验中用到的测试的example.c的文件内容///////////////////////////////////////////////////////////////////////////////////////////////////////#includestdio.hvoidmian(){inta=10,b=5;if(ab){printf(aissmallerthanb);}elseif(ab){printf(aisbiggerthanb);}else{do{a=b+a;b=a*b;break;}while(a==b)}return0;}///////////////////////////////////////////////////////////////////////////////////////////////////////程序运行结果:图1图2【调试情况】程序中,用到了较多的数组和动态数组分配,和较多的循环判断,在动态内存分配时出现了较多的错误,而在关键字和单词的判定中,也出现了不可预知的错误和警告,通过设置断点和插入特殊变量标记法,发现问题并予以解决。【设计技巧】由于此实验是测试验证的实验,在生成此词法程序中,用到了较多的跳转语句,实现程序结构的跳转执行,并利用动态数组来存放一些变量【心得体会】为了能较好的完成此次实验,多次翻阅课本及其他资料,加深了解词法分析的原理和实现所需注意事项,并最终明白和深一步理解了词法分析的过程,认识到词法分析的重要性,词法分析与语法分析本是功能相似,而由此实验更是加强了对此的理解。步掌握了常用的语法分析方法。图3图4