编译原理实验报告

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

中南林业科技大学实验报告课程名称:编译原理专业班级:2012级计算机科学与技术2班姓名:陈晓燚学号:201245802015年7月8日实验一词法分析一、实验目的编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。二、实验题目如源程序为C语言。输入如下一段:main(){inta=-5,b=4,j;if(a=b)j=a-b;elsej=b-a;}要求输出如下:(2,”main”)(5,”(”)(5,”)”)(5,”{”)(1,”int”)(2,”a”)(4,”=”)(3,”-5”)(5,”,”)(2,”b”)(4,”=”)(3,”4”)(5,”,”)(2,”j”)(5,”;”)(1,”if”)(5,”(”)(2,”a”)(4,”=”)(2,”b”)(5,”)”)(2,”j”)(4,”=”)(2,”a”)(4,”-”)(2,”b”)(5,”;”)(1,”else”)(2,”j”)(4,”=”)(2,”b”)(4,”-”)(2,”a”)(5,”;”)(5,”}”)三、实验理论依据(一)识别各种单词符号1、程序语言的单词符号一般分为五种:(1)关键字(保留字/基本字)if、while、begin…(2)标识符:常量名、变量名…(3)常数:34、56.78、true、‘a’、…(4)运算符:+、-、*、/、〈、and、or、….(5)界限符:,;(){}/*…2、识别单词:掌握单词的构成规则很重要(1)标识符的识别:字母|下划线+(字母/数字/下划线)(2)关键字的识别:与标识符相同,最后查表(3)常数的识别(4)界符和算符的识别3、大多数程序设计语言的单词符号都可以用转换图来识别,如图1-1图1-14、词法分析器输出的单词符号常常表示为二元式:(单词种别,单词符号的属性值)(1)单词种别通常用整数编码,如1代表关键字,2代表标识符等(2)关键字可视其全体为一种,也可以一字一种。采用一字一种得分法实际处理起来较为方便。(3)标识符一般统归为一种(4)常数按类型(整、实、布尔等)分种(5)运算符可采用一符一种的方法。(6)界符一般一符一种的分法。(二)超前搜索方法1、词法分析时,常常会用到超前搜索方法。如当前待分析字符串为“a+”,当前字符为“”,此时,分析器倒底是将其分析为大于关系运算符还是大于等于关系运算符呢?显然,只有知道下一个字符是什么才能下结论。于是分析器读入下一个字符’+’,这时可知应将’’解释为大于运算符。但此时,超前读了一个字符’+’,所以要回退一个字符,词法分析器才能正常运行。又比如:‘+’分析为正号还是加法符号(三)预处理预处理工作包括对空白符、跳格符、回车符和换行符等编辑性字符的处理,及删除注解等。由一个预处理子程序来完成。四、词法分析器的设计1、设计方法:(1)写出该语言的词法规则。(2)把词法规则转换为相应的状态转换图。(3)把各转换图的初态连在一起,构成识别该语言的自动机(4)设计扫描器2、把扫描器作为语法分析的一个过程,当语法分析需要一个单词时,就调用扫描器。扫描器从初态出发,当识别一个单词后便进入终态,送出二元式图1-2取单词程序框图五、程序代码#includestdio.h#includestring#includectype.hFILE*fp;charcbuffer;char*key[14]={main,if,else,for,while,do,return,break,continue,int,float,double,boolean,long};intatype,id=4;//判断单词是保留字还是标识符intsearch(charsearchchar[],intwordtype){inti=0;intp;switch(wordtype){开始读标识符是字母掠过空格和回车符查保留字表是否查到换成属性字结束是数字是特殊符号error取数换成属性字换成属性字换成属性字YNYYYNNNcase1:for(i=0;i=13;i++){if(strcmp(key[i],searchchar)==0){//是保留字则p为非0且不重复的整数p=i+1;break;}elsep=0;//不是保留字则用于返回的p=0}return(p);}}chardigitprocess(charbuffer){inti=-1;chardigittp[20];while((isdigit(buffer))||buffer=='.'){digittp[++i]=buffer;buffer=fgetc(fp);}digittp[i+1]='\0';printf((%s,常数)\n,digittp);id=3;returnbuffer;}charalphaprocess(charbuffer){intatype;//保留字数组中的位置inti=-1;charalphatp[20];while((isalpha(buffer))||(isdigit(buffer))||buffer=='_'){alphatp[++i]=buffer;buffer=fgetc(fp);}//读一个完整的单词放入alphatp数组中alphatp[i+1]='\0';//对此单词调用search函数判断类型atype=search(alphatp,1);if(atype!=0){printf(%s,(基本保留字,%d)\n,alphatp,atype-1);id=1;}else{printf((%s,标识符)\n,alphatp);id=2;}returnbuffer;}charotherprocess(charbuffer){charch[20];ch[0]=buffer;ch[1]='\0';if(ch[0]==','||ch[0]==';'||ch[0]=='{'||ch[0]=='}'||ch[0]=='('||ch[0]==')'){printf((%s,分隔符)\n,ch);buffer=fgetc(fp);id=4;return(buffer);}if(ch[0]=='='||ch[0]=='!'||ch[0]==''||ch[0]==''){buffer=fgetc(fp);if(buffer=='='){ch[1]=buffer;ch[2]='\0';printf((%s,运算符)\n,ch);}else{printf((%s,运算符)\n,ch);id=4;return(buffer);}buffer=fgetc(fp);id=4;return(buffer);}if(ch[0]=='+'||ch[0]=='-'){//在当前符号以前是运算符,则此时为正负号if(id==4){buffer=fgetc(fp);//如果是-53显示结果为(-5,3)(3,3)/*ch[1]=buffer;ch[2]='\0';*///显示为(-53,3)inti=1;while((isdigit(buffer))){ch[i]=buffer;buffer=fgetc(fp);i++;}ch[i]='\0';printf((%s,常数)\n,ch);id=3;buffer=fgetc(fp);return(buffer);}//添加++--功能if(id==2){buffer=fgetc(fp);if(buffer==ch[0]){ch[1]=buffer;ch[2]='\0';}printf((%s,运算符)\n,ch);id=4;buffer=fgetc(fp);return(buffer);}ch[1]='\0';printf((%s,运算符)\n,ch);buffer=fgetc(fp);id=4;return(buffer);}}voidmain(){//以只读方式打开一个文件if((fp=fopen(example.c,r))==NULL)printf(error);else{//fgetc()函数:从磁盘文件读取一个字符cbuffer=fgetc(fp);while(cbuffer!=EOF){//掠过空格和回车符if(cbuffer==''||cbuffer=='\n')cbuffer=fgetc(fp);elseif(isalpha(cbuffer))//如果该字符是字母cbuffer=alphaprocess(cbuffer);elseif(isdigit(cbuffer))//如果该字符是数字cbuffer=digitprocess(cbuffer);else//是其他字符cbuffer=otherprocess(cbuffer);}}}六、实验结果七.实验增加内容:①.判断了小数的情况;②.添加了自增,自减运算。实验二LL(1)分析法一、实验目的根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对预测分析LL(1)分析法的理解。二、实验题目实验规定对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E::=TG(2)G::=+TG(3)G::=ε(4)T::=FS(5)S::=*FS(6)S::=ε(7)F::=(E)(8)F::=i若输入串为i+i*i#,则输出为:LL(1)的分析表为:i+*()#说明EeeSelect(E→TG)={(,i}Ggg1g1Select(G→+TG)={+}Select(G→є)={#,)}#Ei+i*i##GTi+i*i##GSFi+i*i##GSii+i*i##GS+i*i##G+i*i##GT++i*i#…………T→FS2……….…+7G→+TG6S→є5i4F→i3E→TG1产生式剩余串分析栈步骤TttSelect(T→FS)={(,i}Ss1ss1s1Select(S→*FS)={*}Select(S→є)={#,)+}Ff1fSelect(F→(E))={(}Select(F→i)={i}三、程序代码#includestdio.h#includestring#includestdlib.h#includedos.hcharA[20];//分析串charB[20];//剩余串charv1[20]={'i','+','*','(',')','#'};//终结符charv2[20]={'E','G','T','S','F'};//非终结符intj=0,b=0,top=0,l;//l为输入串的长度//生产式类型定义typedefstructtype{//大写字符charorigin;//产生式右边字符chararray[5];//字符个intlength;}type;//结构体变量typee,t,g,g1,s,s1,f,f1;//预测分析表typeC[10][10];//输出分析栈voidprint(){inta;//指针for(a=0;a=top+1;a++){printf(%c,A[a]);}printf(\t\t);}//输出剩余串voidprint1(){intj;//输出对齐符for(j=0;jb;j++){printf();}for(j=b;j=l;j++){printf(%c,B[j]);}printf(\t\t\t);}voidmain(){intm,n,k=0,flag=0,finish=0;charch,x;typecha;//把文法产生式赋值结构体e.origin='E';strcpy(e.array,TG);e.length=2;t.origin='T';strcpy(t.array,FS);t.length=2;g.origin='G';strcpy(g.array,+TG);g.length=3;g1.origin='G';g1.array[0]='^';g1.length=1;s.origin='S';strcpy(s.array,*F

1 / 25
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功