编译原理实验报告(一)----词法分析程序【目的要求】通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。【题目分析】本实验以用户指定的想编译的以C语言编写的文件作为词法分析程序的输入数据。在进行词法分析中,先自文件头开始以行为单位扫描程序,将该行的字符读入预先设定的一个数组缓冲区中,然后对该数组的字符逐词分割,进行词法分析,将每个词分割成关键字、标识符、常量和运算符四种词种,最终产生四个相对应的表,即关键字表、标识符表、常量表和运算符表,它们以文件的形式进行存储。除此之外,还产生一个编译后的文件,它指定了每个词在四个表中的位置。【实验过程】下面就词法分析程序中的文件和主要变量进行说明:文件:cpile.c主程序文件key.txt关键字文件operation.txt运算符文件id.txt标识符文件const.txt常量文件after_com.txt编译后产生的文件主要变量:FILE*sfp,*nfp,*ifp,*kfp,*cfp,*pfp;charib[50][20]标识符表(动态生成)charcb[50][10]常量表(动态生成)charkb[44][10]关键字表(预先定义好的)charpb[36][5]运算符表(预先定义好的)主要的子函数名:intnumber(chars[],inti);数字处理函数intletter(chars[],inti);字符处理函数intoperation(chars[],inti);运算符处理函数voidseti(chars[]);标识符建立函数voidsetc(chars[]);常量建立函数voidcfile(chars1[],chars2[],intm);将词和词所在表中位置写入编译后文件voiderror1(chars[]);字符处理出错报告voiderror2(chars[]);标识符处理出错报告voiderror3(chars[]);运算符处理出错报告voidopenall();打开所有文件voidwriteall();将四个表写入文件voidcloseall();关闭所有文件下面简要分析一下词法分析程序的运行流程:否能是否能否打开所要编译的C语言文件报错从源程序中读入一行到数组缓冲区判断当前字符是否是文件结束符结束是否是否是否是否【程序调试】现有源程序a.c清单如下:#includestdio.hintmain(intargc,char*argv[]){charch;inti;ch='a';ch=ch+32;i=ch;printf(%did%c\n,i,ch);/*打印*/return0;}运行词法分析程序后,显示如下结果:after_com.txt文件:#[p--2]include[i--0][p--14]stdio.h[i--1][p--16]int[k--2]main[i--2]([p--7]int[k--2]argc[i--3],[p--6]char[k--0]*[p--9]argv[i--4][[p--18]][p--21])[p--8]判断当前字符是否是’\n’判断当前字符是否是字母判断当前字符是否是数字判断当前字符是否是运算符转关键字和标识符处理转数字处理转运算符处理{[p--23]char[k--0]ch[i--5];[p--13]int[k--2]i[i--6];[p--13]ch[i--5]=[p--15]'[p--19]a[i--7]'[p--19];[p--13]ch[i--5]=[p--15]ch[i--5]+[p--10]32[c--0];[p--13]i[i--6]=[p--15]ch[i--5];[p--13]printf[k--33]([p--7][p--1]%[p--4]d[i--8]id[i--9]%[p--4]c[i--10]\[p--20]n[i--11][p--1],[p--6]i[i--6],[p--6]ch[i--5])[p--8];[p--13]return[k--28]0[c--1];[p--13]}[p--25]key.txt关键字文件:0char1short2int3unsigned4long5float6double7struct8union9void10enum11signed12const13volatile14typedef15auto16register17static18extem19break20case21continue22default23do24else25for26goto27if28return29switch30while31sizeof32txt33printf34FILE35fopen36NULL37fclose38exit39r40read41close42w43fprintfid.txt标识符文件:0include1stdio.h2main3argc4argv5ch6i7a8d9id10c11noperation.txt运算符文件:0!12#3$4%5&6,7(8)9*10+11-12:13;1415=1617?18[19'20\21]22.23{24||25}26!=27=28=29==30++31--32&&33/*34*/const.txt常量文件:03210结果完全正确。词法分析程序如下:#includestdio.h#includestring.h#includestdlib.h#includectype.h#defineSIZE256#definenull0intline=0,error=0,mark1=0,mark2=0;char*sname;FILE*sfp,*nfp,*ifp,*kfp,*cfp,*pfp;/*--------------------------------------------------------------------*/charib[50][20];charcb[50][10];charkb[44][10]={char,short,int,unsigned,long,float,double,struct,union,void,enum,signed,const,volatile,typedef,auto,register,static,extem,break,case,continue,default,do,else,for,goto,if,return,switch,while,sizeof,txt,printf,FILE,fopen,NULL,fclose,exit,r,read,close,w,fprintf};charpb[36][5]={!,\,\#,\$,%,&,,,(,),*,+,-,:,;,,=,,?,[,',\\,],.,{,||,},!=,=,=,==,++,--,&&,/*,*/};/*----------定义了四个二元数组存放四个表--------------------------------*/intmain(intargc,char*argv[]){charsbuff[SIZE];charnbuff[SIZE];inti;/*---------------------------------------------------------------------*/intnumber(chars[],inti);intletter(chars[],inti);intoperation(chars[],inti);voidseti(chars[]);voidsetc(chars[]);voidcfile(chars1[],chars2[],intm);voiderror2(chars[]);voiderror1(chars[]);voiderror3(chars[]);voidopenall();voidwriteall();voidcloseall();/*---------------------------------------------------------------------*/if(argc!=2){printf(Pleaseinputthefileyouwanttocompile:\n);exit(1);}elsesname=argv[1];sfp=fopen(argv[1],r);openall();i=0;while(i50){strcpy(ib[i],);strcpy(cb[i],);i++;}/*---------------------------------------------------------------------*/while(fgets(sbuff,SIZE,sfp)){i=0;line++;/*以行的方式读取源代码进行编译*/while(sbuff[i]!='\n'){if(isalpha(sbuff[i]))/*处理关键字和标识符*/i=letter(sbuff,i);elseif(isdigit(sbuff[i]))i=number(sbuff,i);/*处理数字常量*/elsei=operation(sbuff,i);/*处理运算符*/}fputc('\n',nfp);}/*---------------------------------------------------------------------*/if(error)printf(!Thereare%derrors.,error);/*最后错误个数报告*/elseprintf(Successtocompilethefile.);writeall();closeall();return0;}/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/voidopenall()/*打开所有必需的文件*/{kfp=fopen(key.txt,w+);/*打开关键字表*/pfp=fopen(operation.txt,w+);/*打开运算符表*/cfp=fopen(const.txt,w+);/*打开常量文件*/ifp=fopen(id.txt,w+);/*打开标识符文件*/nfp=fopen(after_com.txt,w+);/*打开编译后会产生的文件*/if(kfp==NULL||cfp==NULL||ifp==NULL||pfp==NULL||nfp==NULL){printf(Cannotopenthesefiles);/*打开文件有错,退出程序*/exit(0);}}/*-----------------------------------------------------------------*/voidwriteall(){intm=0;while(m36&&pb[m]!=){fprintf(pfp,%d%s%s\n,m,,pb[m]);m++;}m=0;while(m44&&kb[m]!=){fprintf(kfp,%d%s%s\n,m,,kb[m]);m++;}m=0;while(mmark2&&cb[m]!=){fprintf(cfp,%d%s%s\n,m,,cb[m]);m++;}m=0;while(mmark1&&ib[m]!=){fprintf(ifp,%d%s%s\n,m,,ib[m]);m++;}}/*-------------------------------------------------------------------*/voidcloseall()/*关闭所有文件*/{fclose(kfp);fclose(pfp);fclose(cfp);fclose(ifp);fclose(nfp);}/*$$$$$$$$$$