您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 西安交大编译原理词法分析器实验报告
编译原理课内实验报告学生姓名石磊专业/班级计算机26学号2120505140所在学院电信学院提交日期2014-10-2一:实验目的:1.强化对系统软件综合工程实现能力的训练;2.加强对词法分析原理、方法和基本实现技术的理解;二:实验内容用C语言或者其他的高级语言作为宿主语言完成C1语言的词法分析器的设计和实现。三:实验功能描述该程序要实现的是一个读单词的过程,从输入的源程序中,识别出各具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依此输出各个单词的内部编码以及单词符号自身的意义。四:设计思想设计该词法分析器的过程中虽然没有实际将所有的状态转移表建立出来,但是所用的思想是根据状态转移表来实现对单词的识别。首先构造一个保留字表,然后每输入一个字符就检测应该进入什么状态,并将该字符连接到d串后继续输入。如此循环,最后根据所在的接受状态以及保留字表识别单词。五:实验程序代码C0语言如下:%{#includestdio.h#includestdlib.h#includestring.hintyywrap();intlineno=1;%}delim[\t]ws{delim}+letter[A-Za-z]digit[0-9]id{letter}({letter}|{digit})*number{digit}+error_id({digit})+({letter})+enter[\n]spchar({|}|[|]|(|)|;|=|,)ariop(+|-|*|/)relop(|=||=|==|!=)comment\/\*(\*[^/]|[^*])*\*\/reswd(int|else|return|void|if|while|include)%%{ws}{}{comment}{}{enter}{lineno++;}{reswd}{fprintf(yyout,%d行\t关键字\t%s\n,lineno,yytext);}{spchar}{fprintf(yyout,%d行\t标识符\t%s\n,lineno,yytext);}{id}{fprintf(yyout,%d行\t保留字\t%s\n,lineno,yytext);}{number}{fprintf(yyout,%d行\t数字\t%s\n,lineno,yytext);}{error_id}{fprintf(yyout,%d行\t出错\t%s\n,lineno,yytext);}{ariop}{fprintf(yyout,%d行\t左括号\t%s\n,lineno,yytext);}{relop}{fprintf(yyout,%d行\t右括号\t%s\n,lineno,yytext);}%%intyywrap(){return1;}intmain(void){yylex();return0;}cmd运行截图:测试程序如下:#includestdio.hintmain(){inta,b,c;if(ab){c=a;a=b;b=c}return0;}分析结果如下:#1行关键字include1行右括号1行保留字stdio.1行保留字h1行右括号2行关键字int2行保留字main2行标识符(2行标识符)3行标识符{4行关键字int4行保留字a4行标识符,4行保留字b4行标识符,4行保留字c4行标识符;5行关键字if5行标识符(5行保留字a5行右括号5行保留字b5行标识符)6行标识符{6行保留字c6行标识符=6行保留字a6行标识符;7行保留字a7行标识符=7行保留字b7行标识符;8行保留字b8行标识符=8行保留字c9行标识符}10行关键字return10行数字010行标识符;11行标识符}C程序实现程序代码如下:#includestdio.h#includestring.hvoidmain(){inti=0,j,k=0,state=1,f=0,linenum=1;chara[11][10]={const,var,call,begin,if,while,do,odd,end,then,procedure};charb,d[40]={\0};freopen(input.txt,r,stdin);freopen(output.txt,w,stdout);b=getchar();while(b!=EOF)/*判断所输入字符是否为结束符*/{if(b==''||b=='\n'||b=='\t')/*滤过空格、换行等分隔符号*/{if(b='\n')linenum++;b=getchar();}elseif((b='a'&&b='z')||(b='A'&&b='Z'))/*识别标识符以及保留字*/{d[i++]=b;b=getchar();while((b='a'&&b='z')||(b='A'&&b='Z')||(b='0'&&b='9')){d[i++]=b;b=getchar();}for(j=0;j11;j++)/*查询保留字表确定该单词是否是保留字*/{if(strcmp(d,a[j])==0){printf(保留字:%s\n,d);k=1;break;}}if(k==0)/*在保留字表中没有查到该单词,是标识符*/printf(标识符:%s\n,d);for(j=0;j=i;j++)d[j]='\0';i=0;k=0;}elseif(b='0'&&b='9')/*识别常数*/{d[i++]=b;b=getchar();while(f!=1){switch(state){case1:if(b='0'&&b='9'){state=1;d[i++]=b;b=getchar();}elseif(b=='.'){state=2;d[i++]=b;b=getchar();}elseif(b=='E'){state=4;d[i++]=b;b=getchar();}elsestate=7;break;case2:if(b='0'&&b='9'){state=3;d[i++]=b;b=getchar();}elsestate=8;break;case3:if(b='0'&&b='9'){state=3;d[i++]=b;b=getchar();}elseif(b=='E'){state=4;d[i++]=b;b=getchar();}elsestate=7;break;case4:if(b=='+'||b=='-'){state=5;d[i++]=b;b=getchar();}elseif(b='0'&&b='9'){state=6;d[i++]=b;b=getchar();}elsestate=8;break;case5:if(b='0'&&b='9'){state=6;d[i++]=b;b=getchar();}elsestate=8;break;case6:if(b='0'&&b='9'){state=6;d[i++]=b;b=getchar();}elsestate=7;break;case7:f=1;break;case8:f=1;break;}}if(state==7&&(b'a'||b'z')&&(b'A'||b'Z'))printf(常数:%s\n,d);elseif(state==7&&(b='a'&&b='z')||(b='A'&&b='Z'))/*数字后接字母的出错控制*/{while((b='a'&&b='z')||(b='A'&&b='Z')){d[i++]=b;b=getchar();}printf(errorline%d\n,linenum);}elseprintf(errorline%d\n,linenum);for(j=0;j=i;j++)d[j]='\0';i=0;f=0;state=1;}elseif(b=='')/*识别''、'='和''*/{d[i++]=b;b=getchar();if(b=='='||b==''){d[i++]=b;b=getchar();printf(结束运算符:%s\n,d);for(j=0;j=i;j++)d[j]='\0';i=0;}else{printf(开始运算符:%s\n,d);for(j=0;j=i;j++)d[j]='\0';i=0;}}elseif(b=='')/*识别''和'='*/{d[i++]=b;b=getchar();if(b=='='){d[i++]=b;b=getchar();printf(运算符:%s\n,d);for(j=0;j=i;j++)d[j]='\0';i=0;}else{printf(终结运算符:%s\n,d);for(j=0;j=i;j++)d[j]='\0';i=0;}}elseif(b==':')/*识别':='*/{d[i++]=b;b=getchar();if(b=='='){d[i++]=b;b=getchar();printf(赋值运算符:%s\n,d);}elseprintf(errorline%d\n,linenum);for(j=0;j=i;j++)d[j]='\0';i=0;}elseif(b=='*'||b=='+'||b=='-'||b=='/'||b=='=')/*识别运算符*/{printf(算术运算符:%c\n,b);b=getchar();}elseif(b=='('||b==')'||b==','||b==';'||b=='.')/*识别分隔符*/{printf(分隔符:%c\n,b);b=getchar();}else{printf(errorline%d\n,linenum);b=getchar();}}}测试程序如下:#includestdio.hintmain(){inta,b,c;if(ab){c=a;a=b;b=c}return0;}分析输出结果如下:errorline1标识符:include开始运算符:标识符:stdio分隔符:.标识符:h终结运算符:标识符:int标识符:main分隔符:(分隔符:)errorline5标识符:int标识符:a分隔符:,标识符:b分隔符:,标识符:c分隔符:;保留字:if分隔符:(标识符:a终结运算符:标识符:b分隔符:)errorline9标识符:c算术运算符:=标识符:a分隔符:;标识符:a算术运算符:=标识符:b分隔符:;标识符:b算术运算符:=标识符:cerrorline12标识符:return常数:0分隔符:;errorline15六:实验心得在本次实验中,我耗费了大量时间来设计分析设计。用了一个多小时在纸上设计,编程总共用了三四个小时。耗费了大量的时间在搭建环境上面。也不是很清楚在cmd中应该用哪些指令,每一步该如何实现。为了解决这个问题,我在百度上查了很多相关材料,并且积极与同学交流,终于解决了问题。可是,后来运行又出现了问题。不过在生成lex.yy.c文件后,通过vc6.0可以生成exe,也可以使后续工作可以继续。为了使报告可以更完善,我用同学的电脑运行了a.lex文件,也顺利得到了exe以及输出结果。本次c程序比较冗长,还有很多需要改进的地方。通过本次实验,体会到了cmd的强大功能以及flex的神奇之处。在分别用flex和c语言实现了词法分析设计以后,通过对比可以发现用flex要比用c语言实现方便的多。也体会到了互联网的方便之处,以后应多自己探索,发现一些东西,学会自主学习。
本文标题:西安交大编译原理词法分析器实验报告
链接地址:https://www.777doc.com/doc-2036113 .html