编译原理—词法分析器实验报告张雅梅(10072510308)一、实验目的:1.设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。2.掌握在对程序设计语言的源程序扫描的过程中,将其分解后各类单词的语法分析方法。二、实验要求:1.对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。2.本程序自行规定:(1)关键字begin,end,if,then,else,while,write,read,do,call,const,char,until,procedure,repeat(2)运算符:+,-,*,/,=(3)界符:{,},[,],;,,,.,(,),:(4)其他标记如字符串,表示以字母开头的标识符。(5)空格、回车、换行符跳过。在屏幕上显示如下:(1,无符号整数)(begin,关键字)(if,关键字)(+,运算符)(;,界符)(a,普通标识符)三、使用环境:Windowvista下的VisualStudio2008;四、实验步骤1.查询资料,了解词法分析器的工作过程与原理。2.分析题目,整理出基本设计思路。3.实践编码,将设计思想转换用c语言编码实现,编译运行。4.测试功能,多次设置包含不同字符,关键字的待解析文件,仔细察看运行结果,检测该分析器的分析结果是否正确。通过最终的测试发现问题,逐渐完善代码中设置的分析对象与关键字表,拓宽分析范围提高分析能力。五、流程图五、调试程序:1.举例说明文件位置:C:\TEST.txt目标程序如下:Intmain(){i=10;j=100;n=1;sum=0;mult=1;while(i0){n=n+1;i=i-1;}if(j=50)thensum=sum+j;else{mult=mult*(j+1);sum=sum+i;}if(i=10)thensum=sum-i;elsemult=mult+i/2;if(i==j)thensum=sum-j;elsemult=mult-j/2;if(n1)thenn=n-1;elsen=n+1;if(n2)thenn=n+2;elsen=n-2;}2.运行结果:六、程序源代码:#includeiostream#includestringusingnamespacestd;#defineMAX22charch='';stringkey[15]={begin,end,if,then,else,while,write,read,do,call,const,char,until,procedure,repeat};intIskey(stringc){//关键字判断inti;for(i=0;iMAX;i++){if(key[i].compare(c)==0)return1;}return0;}intIsLetter(charc){//判断是否为字母if(((c='z')&&(c='a'))||((c='Z')&&(c='A')))return1;elsereturn0;}intIsDigit(charc){//判断是否为数字if(c='0'&&c='9')return1;elsereturn0;}voidanalyse(FILE*fpin){stringarr=;while((ch=fgetc(fpin))!=EOF){arr=;if(ch==''||ch=='\t'||ch=='\n'){}elseif(IsLetter(ch)){while(IsLetter(ch)||IsDigit(ch)){if((ch='Z')&&(ch='A'))ch=ch+32;arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);if(Iskey(arr)){coutarr\t$关键字endl;}elsecoutarr\t$普通标识符endl;}elseif(IsDigit(ch)){while(IsDigit(ch)||ch=='.'&&IsDigit(fgetc(fpin))){arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);coutarr\t$无符号实数endl;}elseswitch(ch){case'+':case'-':case'*':case'=':case'/':coutch\t$运算符endl;break;case'(':case')':case'[':case']':case';':case'.':case',':case'{':case'}':coutch\t$界符endl;break;case':':{ch=fgetc(fpin);if(ch=='=')cout:=\t$运算符endl;else{cout=\t$运算符endl;;fseek(fpin,-1L,SEEK_CUR);}}break;case'':{ch=fgetc(fpin);if(ch=='=')cout=\t$运算符endl;if(ch=='')cout\t$输入控制符endl;else{cout\t$运算符endl;fseek(fpin,-1L,SEEK_CUR);}}break;case'':{ch=fgetc(fpin);if(ch=='=')cout=\t$运算符endl;elseif(ch=='')cout\t$输出控制符endl;elseif(ch=='')cout\t$运算符endl;else{cout\t$运算符endl;fseek(fpin,-1L,SEEK_CUR);}}break;default:coutch\t$无法识别字符endl;}}}voidmain(){charin_fn[30];FILE*fpin;cout请输入源文件名(包括路径和后缀名):;for(;;){cinin_fn;if((fpin=fopen(in_fn,r))!=NULL)break;elsecout文件路径错误!请输入源文件名(包括路径和后缀名):;}cout\n********************分析如下*********************endl;analyse(fpin);fclose(fpin);coutendl;cout按任意键结束endl;inta;cina;}六、实验心得:通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,使用某种高级语言(例如C++语言)直接编写此法分析程序。另外,也让我重新熟悉了C++语言的相关内容,加深了对C++语言的用途的理解。在本次实验中,我纠正了一个一直以来的概念错误:main不是关键字,它定义为程序的入口,是主函数!在本实验中,虽然我把main初始化在关键字表(字符指针类型数组)*Key[10]中,当与该数组中字符串进行比较时,若与main匹配成功,则返回2,若为其他关键字则返回1,以此来把main从关键字中区别出来。在本实验中的关键字表只初始化了几个常用的关键字,还可继续扩充(只需扩大数组,向其中补充要添加的关键字)。