第1页共23页实验报告学院(系)名称:计算机与通信工程学院姓名学号专业计算机科学与技术班级实验项目实验一:词法分析课程名称编译原理课程代码实验时间2016/03/172016/03/22实验地点软件实验室7-219批改意见成绩教师签字:实验内容:实现标准C语言词法分析器。实验要求:(1)单词种别编码要求基本字、运算符、界符:一符一种标识符:统一为一种;常量:按类型编码;(2)词法分析工作过程中建立符号表、常量表。并以文本文件形式输出。(3)词法分析的最后结果以文本文件形式输出。第2页共23页实验源代码和心得体会#includeiostream#includectype.h#includecstring#definebufsize1024//关键字#defineINCLUDE256#defineAUTO257#defineBREAK258#defineCASE259#defineCHAR260#defineCONST261#defineCONTINUE262#defineDEFAULT263#defineDO264#defineDOUBLE265#defineELSE266#defineENUM267#defineEXTERN268#defineFLOAT269#defineFOR270#defineGOTO271#defineIF272#defineINT273#defineLONG274#defineREGISTER275#defineRETURN276#defineSHORT277#defineSIGNED278#defineSIZEOF279#defineSTATIC280#defineSTRUCT281#defineSWITCH282#defineTYPEDEF283#defineUNION284#defineUNSIGNED285#defineVOLATILE286#defineWHILE287//运算符#definePLUS288//+#defineMINUS289//-#defineMUL290//*#defineDIV291///#defineREMAIN292//%#defineGREATER293//第3页共23页#defineLESS294//#defineEQUAL295//=#defineMISTAKE296//!#defineAND297//defineOR298//|#definePP299//++#defineMM300//--#defineEE301//==#defineGE302//=#defineLE303//=#defineMISE304//!=#defineAA305//&defineOO306//||#definePE307//+=#defineMINUSE308//-=#defineMULE309//*=#defineDIVE310///=#definePOW311//^//界符#defineSEMIC312//;#defineCOMMA313//,#defineMULANNO_L314///*#defineMULANNO_R315//*/#defineBRACE_L316//{#defineBRACE_R317//}#defineBRAKET_L318//(#defineBRAKET_R319//)#defineMIDBRA_L320//[#defineMIDBRA_R321//]#defineONE_ANNO322//////标识符和常量符#defineTAG400#defineCONINT401#defineCONFLOAT402#defineCONCHAR403#defineCONSTRING404//转义字符和字符串#defineCA500#defineCB501#defineCF502#defineCN503#defineCR504#defineCT505#defineCV506#defineCBSL507第4页共23页#defineCQUE508#defineCDQM509#defineCQM510#defineZERO511usingnamespacestd;typedefstructVariate{//变量标识符intid;charname[50];}Variate;typedefstructConstant{//常量intid;charname[50];}Constant;typedefstructSign{charname[100];intsym;charattr[100];}Sign;constchar*keywordTable[]={include,auto,break,case,char,const,continue,default,do,double,else,enum,extern,float,for,goto,if,int,long,register,return,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,volatile,while,,##};//##作用是判断是否结束constchar*operateTable[]={+,-,*,/,%,,,=,!,&,|,++,--,==,=,=,!=,&&,||,+=,-=,*=,/=,^,##};constchar*borderTable[]={;,,,/*,*/,{,},(,),[,],//,##};constcharchangeList[12]={'a','b','f','n','r','t','v','\\','?','','\'','0'};FILE*in;FILE*Out;FILE*Error;intline=1;//用于输出错误的行数或者其他情况。默认值是从1开始,为第一行charbuf[bufsize];//存储读取的一行的字符串charfirchar;//头文件下第一个字符charChar;intstart=0;intVariateNum=0;//记录变量的个数,减去1intConstantNum=0;//记录常量的个数intSignNum=0;//记录标记的个数intnotation=1;//记录是否找到多行注释的另一半*/,默认值是1即为有另一半intisNotation=0;//判断是否是在注释行内0不是,1单行注释2多行注释boollast=false;intlate=0;Variatevar;Constantcon;Signsign;第5页共23页VariateVarArr[bufsize];ConstantConArr[bufsize];SignSigArr[bufsize];//获取读取的文件本行的第一个字符,直到找到一个非空格字符chargetfirstc(FILE*in){charch=fgetc(in);//fgetc()函数的作用是读取文件的当前行的一个字符,返回读取的字符while(ch==''||ch=='\n'||ch=='\t'){if(ch=='\n'){line++;fputc('\n',Out);//向输出的文本文件中打印换行}ch=fgetc(in);}returnch;}//处理读取的本行内容voiddealhead(char*buf){charch[10];charcha;charstr[bufsize];inti=0;intj=0;inttemp=0;while(ibufsize)//找到include并保存{if(buf[i]!=''&&buf[i]!='\0'){if(temp==0){if(buf[i]=='i')temp=1;elseif(buf[i]=='d')temp=2;else{fprintf(Error,Line:%d\tformatiswrong!Without''\n,line);break;}}if(temp==1){第6页共23页ch[j]=buf[i];j++;if(buf[i]==''){ch[j]='\0';break;}}elseif(temp==2){ch[j]=buf[i];j++;if(buf[i+1]==''){ch[j]='\0';i++;break;}}}i++;}if(temp==1){intindex=0;fputc('#',Out);while(buf[index]!='\0'){if(buf[index]!='')fputc(buf[index],Out);index++;}if(strcmp(ch,include)==0){i++;//因为上面程序没进行++就直接break所以这里就需要加1到下一个角标while((cha=buf[i])!=''){i++;if(cha=='\n'){fprintf(Error,Line:%d\tincludeendwithout''\n,line);break;}}}第7页共23页elsefprintf(Error,Line:%d\tincludeformatiswrong\n,line);}elseif(temp==2){if(strcmp(ch,define)!=0){i++;while((cha=buf[i])==''){if(cha=='\n'){//fprintf(Error,Line:%d\tincludeendwithout''\n,line);break;}i++;}if(buf[i]!=''){if(!(isalpha(buf[i])))fprintf(Error,Line:%d\tdefineformatiswrong\n,line);//此处意思是define后必须有变量名称}}else{//在上面的break之前已经进行过i++;所以这里可以直接用while(!isalpha(buf[i])){if(buf[i]=='\0'){fprintf(Error,Line:%d\tdefinewithoutvatiateandname!\n,line);break;}i++;}intindex=0;intspace=0;//计算在上一个字母之后第几次遇到空格fputc('#',Out);while(buf[index]!='\0'){if(buf[index]!=''){fputc(buf[index],Out);space=0;第8页共23页}else{space++;if(space==1&&index!=0)fputc('',Out);}index++;}}}}//处理头文件charhead(FILE*in){charch;if(late==0)ch=getfirstc(in);elsech=firchar;//即为#while(ch=='#'){fgets(buf,bufsize,in);//fgets()读取in文件当前一行的内容为bufsize-1个字符的内容intlen=strlen(buf);buf[len-1]='\0';dealhead(buf);//这条语句执行完毕后且找到''就说明这行结束line++;ch=getfirstc(in);if(ch=='#')fputc('\n',Out);}returnch;}//判断关键字intkeyword(char*str){inti;for(i=0;keywordTable[i]!=##;i++)if(strcmp(str,keywordTable[i])==0)returni+256;//返回关键字对应的值return-1;}//处理字母voiddealAlpha(){第9页共23页charstr[50];Variatevar;Signsign;inti;intkey;//记录字符串str对应的值。str[0]=firchar;for(i=start;isalpha(buf[i])||isdigit(buf[i]);i