您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 编译原理实验-词法分析器
洛阳理工学院实验报告院部计算机系班级B150402学号姓名课程名称编译原理实验日期2018.6.4实验名称词法分析器成绩实验目的:加深对词法分析过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析;能够使自己编写的程序对简单的程序片段进行词法分析。实验条件:装有Windows操作系统,MicrosoftVisualC++6.0。实验内容:自定义一种程序设计语言,或选择已有的一种高级语言(C语言),编制它的词法分析程序。实验要求:1.对单词的构成规则有明确的定义2.编写的程序能够正确识别源程序中的单词符号3.识别出的单词以种别码,值的形式保存在符号表中4.词法分析中源程序和分析后的符号表均保存在.txt文件中5.有一定的检查错误的能力。遇到错误时可显示“Error”,然后跳过错误部分继续显示。6.实验报告包括以下内容(1)编程思路、流程图、源代码(2)上机调试时发现的问题,以及解决的过程(3)所使用的测试数据及结果(4)心得体会实验步骤1.给出目标语言的所有单词符号及种别编码、单词符号的状态转换图。2.依次读入源程序,对源程序进行单词切分和识别,直到源程序结束。3.对正确的单词,按照它的种别以种别码,值的形式保存在符号表中。4.对不正确的单词,做出错误处理。实验内容:1.编程思路:1.1、实现预处理功能源程序中可能包含有对程序执行无意义的符号,要求将其剔除。首先编制一个源程序的输入过程,从键盘、文件或文本框输入若干行语句,依次存入输入缓冲区(字符型数据);然后编制一个预处理子程序,去掉输入串中的回车符、换行符和跳格符等编辑性文字;把多个空白符合并为一个;去掉注释。1.2、实现词法分析功能输入:所给文法的源程序字符串。输出:将每个单词或数字以及他对应的种别码和类型输出到文件中。具体实现时,可以将单词的二元组用结构进行处理。1.3、待分析的C语言子集的词法1)关键字char,int,if,else,var,return,break,do,while,for,double,float,short2)运算符和界符+-*/===;()[]\|&{}\\#3)空格由空白、制表符和换行符组成空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段通常被忽略。1.4、各种单词符号对应的种别码表1各种单词符号的种别码单词符号种别码char1int2if3else4var5return6break7do8while9for10double11float12short13标识符14数字15符号16-401.5、词法分析程序的主要算法思想算法的基本任务是从文件中读出字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到的单词符号的第一个字符的种类,拼出相应的单词符号,并输出到文件中。2.流程图:2.1主程序流程图主函数流程图是否输入串结束输入编译后的文件名调用分析子程序结束开始输入打开的文件名关闭文件文件为空?是输入串结束是2.2分析函数流程图分析函数流程图3.源代码:#includestdio.h#includeconio.h#includemath.h#includestring.h#includestdlib.hinti,row=0,line=0;chara[1000];//程序intnumber[1000][100];//常数表charmark[100][5];//标识符表FILE*fin,*fout;//词法分析否否是否是符号字母数字否是返回0变量初始化忽略空格是否文件结束获取一个单词获取数字在文件中写入当前单词以及对应的关键字种别码获取一个完整符号返回开始在文件中写入当前单词以及对应的符号种别码在文件中写入当前单词以及对应的符号种别码在文件中写入当前单词以及标识符种别码12将当前单词添加到标识符表中存在于数字表存在于标识符表存在于符号表存在于关键字表是将当前数字添加到数字表中将当前符号添加到符号表中是intwordanalysis(){if((a[i]='A'&&a[i]='Z')||(a[i]='a'&&a[i]='z'))//分析标识符和关键字{charword[10];charkeyWord[100][100]={char,int,if,else,var,return,break,do,while,for,double,float,short};//关键字表intn=0;word[n++]=a[i++];//若字符为A~Z或0~9,则继续读取while((a[i]='A'&&a[i]='Z')||(a[i]='0'&&a[i]='9')||(a[i]='a'&&a[i]='z')){word[n++]=a[i++];}word[n]='\0';i--;//判断该标识符是否为关键字for(n=0;n100;n++){if(strcmp(word,keyWord[n])==0){fprintf(fout,%s\t(%d)\t关键字\n,keyWord[n],n+1);return3;}}//判断该标识符是否存在标识符表中intm=0;if(line!=0){intq=0;while(qline){if(strcmp(word,mark[q++])==0){fprintf(fout,%s\t(14,%d)\t标识符\n,word,q);return3;}}}//将该标识符保存到标识符表中strcpy(mark[line],word);fprintf(fout,%s\t(14,%d)\t标识符\n,word,line+1);line++;return3;}elseif(a[i]='0'&&a[i]='9')//分析常数{charx[100];intn=0,sum;x[n++]=a[i++];//判断字符是否是0~9while(a[i]='0'&&a[i]='9'){x[n++]=a[i++];}x[n]='\0';i--;intnum=atoi(x);//将字符串转换成int型//判断该常数是否存在于常数表中if(row!=0){inty;for(y=0;y1000;y++){intw=number[y][0];sum=0;intd;for(d=1;d=number[y][0];d++){w=w-1;sum=sum+number[y][d]*pow(2,w);}if(num==sum){fprintf(fout,%d\t(15,%d)\n,num,y+1);return3;}}}intz=num,c=num;intm=0;do//计算是几位二进制数{z=z/2;m++;}while(z!=0);for(n=m;n0;n--)//将二进制保存于常数表中{number[row][n]=c%2;c=c/2;}number[row][0]=m;intline=row;fprintf(fout,%d\t(15,%d)\n,num,line+1);row++;return3;}else//分析符号switch(a[i]){case'':case'\n':return-1;case'#':return0;case'=':fprintf(fout,=\t(16)\n);return3;case'':i++;if(a[i]=='='){fprintf(fout,=\t(17)\n);return3;}elseif(a[i]==''){fprintf(fout,\t(18)\n);return3;}else{i--;fprintf(fout,\t(19)\n);return3;}case'':i++;if(a[i]=='='){fprintf(fout,=\t(20)\n);return3;}else{i--;fprintf(fout,\t(21)\n);return3;}case'+':fprintf(fout,+\t(22)\n);return3;case'-':fprintf(fout,-\t(23)\n);return3;case'*':fprintf(fout,*\t(24)\n);return3;case'/':i++;if(a[i]!='/'){i--;fprintf(fout,/\t(25)\n);return3;}else{while(1){if(a[i++]=='\n')return-1;}fprintf(fout,//\t(35)\n);return3;}case':':fprintf(fout,:\t(26)\n);return3;case';':fprintf(fout,;\t(27)\n);return3;case'(':fprintf(fout,(\t(28)\n);return3;case')':fprintf(fout,)\t(29)\n);return3;case'{':fprintf(fout,{\t(30)\n);return3;case'}':fprintf(fout,}\t(31)\n);return3;case'[':fprintf(fout,[\t(32)\n);return3;case']':fprintf(fout,]\t(33)\n);return3;case'|':fprintf(fout,|\t(34)\n);return3;case'':fprintf(fout,\\t(35)\n);return3;case',':fprintf(fout,,\t(36)\n);return3;case'\'':fprintf(fout,'\t(37)\n);return3;//单引号case'&':i++;if(a[i]!='&'){i--;fprintf(fout,&\t(38)\n);return3;}else{fprintf(fout,&&\t(39)\n);return3;}case'\\':fprintf(fout,\\\t(40)\n);return3;}}intmain(){printf(************C语言实现编译原理词法分析器************\n\n);printf(\n);intl=0;intm;i=0;charinput[100],output[100];//输入文件和输出文件的路径和文件名printf(请输入词法分析输入的文件名(包括路径):);scanf(%s,input);printf(请输入词法分析输出的文件名(包括路径):);scanf(%s,output);fin=fopen(input,r);fout=fopen(output,w);if(fin==NULL){printf(打开词法分析输入文件有错\n);return(1);}if(fout==NULL){printf(打开词法分析输出文件有错\n);return(2);//返回错误代码2}printf(\n--------开始进行词法分析--------\n);while(!feof(fin)){a[l++]=fgetc(fin);}a[l]='#';do{m=wordanalysis();switch(m){case-1:i++;break;case0:i++;break;case3:i++;break;}}while(m!=0);fclose(fin);fclose(fout);printf(\n--------词法分析执行完毕--------\n);_getch();return0;}4.上机调试时发现的问题,以及解决的过程:1)文件读取错误。运行程序后,输入文件路径后,显示“打开词法分析输入文件有错”。解决:我看了下程序,没发现什么明显错误,然后看了文件名111.txt,也是对的,点开文件属性,发现文件名显示的是111.txt.txt,意识到机房电脑默认没显示后缀,自己起名字的时候多加了一个.txt;2)运行过程中强行停止。解决:检查了一下程序,
本文标题:编译原理实验-词法分析器
链接地址:https://www.777doc.com/doc-4254590 .html