编译原理词法分析程序实现实验报告_第1页
编译原理词法分析程序实现实验报告_第2页
编译原理词法分析程序实现实验报告_第3页
编译原理词法分析程序实现实验报告_第4页
编译原理词法分析程序实现实验报告_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、实验一 词法分析程序实现一、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。输入:由无符号数和+,*,/, ( , ) 构成的算术表达式,如1.5e+2100。输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。二、 设计部分因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以e为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下:goto 1:goto 2:三、 源程序代码部分#include #include#

2、include #define max 100#define unsignednumber 1#define plus 2#define subtract 3#define multiply 4#define divide 5#define leftbracket 6#define rightbracket 7#define inefficaciouslabel 8#define finish 111int count=0;int class;void storetype();int type100;char store20=0;void showstrfile();/已经将要识别的字符串存在

3、文件a中void output(int a,char *p1,char *p2);/字符的输出过程int sign(char *p);/+-*/整体识别过程int unsignednum(char *p);/是否适合合法的正整数09int legalcharacter(char *p);/是否是合法的字符:sign(p)|unsignednum(p)|e|.void distinguishsign(char *p);/+-*/具体识别过程void typydistinguish();/字符的识别过程void showtype();/将类别码存储在type100中,为语法分析做准备void sh

4、owstrfile()/已经将要识别的字符串存在文件a中file *fp_s;char ch;if(fp_s=fopen(a.txt,r)=null)printf(the file cannot open!); exit(0);elsech=fgetc(fp_s);while(ch!=eof)putchar(ch);ch=fgetc(fp_s);printf(n);void storestr()/将文件中的字符串存储到数组storei file *fp=fopen(a.txt,r);char str;int i=0;while(!feof(fp)fscanf(fp,%c,&str);if(st

5、r=?)storei=0;break;storei=str;i+;storei=0;void showstore()int i;for (i=0;storei!=0;i+) printf(%c,storei);printf(n);void output(int a,char *p1,char *p2) printf(%3st%dt%st,class,a,value);while(p1=p2)printf(%c,*p1);p1+;printf(n);int sign(char *p)char ch=*p;if(ch=+|ch=-|ch=*|ch=/|ch=(|ch=)return 1;elser

6、eturn 0;int unsignednum(char *p)char ch=*p;if(0=ch&ch=9)return 1;elsereturn 0;int legalcharacter(char *p)char ch=*p;if(sign(p)|unsignednum(p)|ch=e|ch=.)return 1;else return 0;void distinguishsign(char *p) int class;char ch=*p;switch(ch) case +: output(plus,p,p);typecount+=plus;break; case -: output(

7、subtract,p,p);typecount+=subtract;break; case *: output(multiply,p,p);typecount+=multiply;break; case /: output(divide,p,p);typecount+=divide;break; case (: output(leftbracket,p,p);typecount+=leftbracket;break; case ): output(rightbracket,p,p);typecount+=rightbracket;break; default: break; void typy

8、distinguish() printf(词法开始,分析结果如下:n); char *p; p=&store0; while(*p!=0) if(sign(p) distinguishsign(p+); continue; else if(unsignednum(p)|*p=.) char *p1=p;if(unsignednum(p)while(unsignednum(p)p+;if(*p=0) output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;continue;else if(*p=e)p+;if(unsignednum(p

9、)while(unsignednum(p)p+;output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;continue;else if(*p=+|*p=-)p+;while(unsignednum(p)p+;output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;continue;else output(inefficaciouslabel,p1,-p);printf(输入的这个符号是不合法的!);break;typecount+=inefficaciouslabel;p+

10、;continue;else if(*p=.)p+;while(unsignednum(p)p+;if(*p=0) output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;continue;else if(*p=e)p+;if(unsignednum(p)while(unsignednum(p)p+;output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;continue;else if(*p=+|*p=-)p+;if(unsignednum(p)while(unsigned

11、num(p)p+;output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;continue;else output(inefficaciouslabel,p1,-p);printf(输入的这个符号是不合法的! /n);break;typecount+=inefficaciouslabel;p+;continue;elseoutput(inefficaciouslabel,p1,-p);printf(输入的这个符号是不合法的!因为他的后面既不是09也不是“+”或者“-);break;/1.5e*2这样的字符串不是无符号数 typecou

12、nt+=inefficaciouslabel;p+;continue;else output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;continue;else output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;continue;if(*p=.)p+;if(unsignednum(p)p+;while(unsignednum(p)p+;if(*p=0) output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;

13、continue;else if(*p=e)p+;if(unsignednum(p)while(unsignednum(p)p+; output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;continue;else if(*p=+|*p=-)p+;while(unsignednum(p)p+;output(unsignednumber,p1,-p);typecount+=unsignednumber;p+;continue;else output(unsignednumber,p1,-p);typecount+=unsignednum

14、ber;p+;continue;else output(inefficaciouslabel,p1,-p); printf(输入的这个符号是不合法的!);break;typecount+=inefficaciouslabel;p+;continue; else if(*p=e) output(inefficaciouslabel,p,p);break; typecount+=inefficaciouslabel; printf(输入的这个符号是不合法的!); p+; continue; printf(nn词法分析完毕!);void showtype()/将类别码存储在type100中,为语法分

15、析做准备 printf(n用类别码表示输入的字符如下:n);int i;printf(n);for(i=0;typei!=finish;i+)printf(%d,typei);printf(nn); void main() /词法分析部分 storestr(); showstore(); typydistinguish(); typecount=finish; showtype(); 四、 实验结果正确的结果:错误的结果:输入的字符串中有1.5e*2因为实验是以文件的形式进行读取的所以,在读取不合法的过程中只是将存在project 中的a.txt 中的内容改变改为1.5e*2+100*555实

16、验结果如下:结果分析:对于正确的结果,我以二元式的形式输出,包括他的值和他的类别码,其中将类别码存放在另外的一个数组中,为了在实验二中的语法识别打下基础。对于错误的结果,我选择的是跳出这个程序,并且能过分析出错的原因。改进设计:(1)字符串是以文件的形式输出的,连续重复输入存在局限性(2)能够跳过错误的字符继续识别剩下的字符实验一扩展李晓萌 088330一、实验内容:试对基础实验识别的单词种类进行扩充,构造识别以下单词的词法分析程序。语言中具有的单词包括五个有代表性的关键字begin、end、if、then、else;标识符;整型常数;六种关系运算符;一个赋值符和四个算术运算符。二、 设计部分

17、基础实验和扩展实验的差别在基础实验的关键在于无符号数的判断,但是,扩展实验的关键在于关键字和标识符的识别。关于关键字的识别,通过和题目中给出的几个关键字的对比,若相同则可以确定是关键字,否则,就可自动确定为标识符具体实现的流程图如下:三、 源程序代码部分#include #include #define begin 1#define end 2#define if 3#define then 4#define else 5# define id 6# define int 7# define lt 8# define le 9# define eq 10# define ne 11# defi

18、ne gt 12# define ge 13#define is 14#define pl 15#define mi 16#define mu 17#define di 18char *keyword5=begin,end,if,then,else; int i=0,j=0,k=0,t=0;/搜索指示器 char ch;/存放最新读入的原程序字符 char strtoken20;/存放构成单词符号的字符串 char * chr_form100;/字符表 char * int_form100;/常数表 char form1000; int q=0; int temp; void getchar(

19、)/将下一个字符读入ch中,搜索指示器前移一字符位 ch=formk; k+; void getbc()/检查ch中的字符是否为空白,若是则调用getchar直至ch中进入 /一个非空白字符 while(ch= ) /k-; getchar(); void concat()/将ch中的字符连接到strtoken之后, strtokeni=ch; i+; bool isletter()/判断ch中的字符是否为字符 if(ch=a)|(ch=a) return (1); else return(0); bool isdigit()/判断ch中的字符是否为数字 /k-; if(ch)=0) retu

20、rn (1); else return (0); int reserve()/对strtoken中的字符串查找保留字表,若它是一个保留字 /则返回它的编码,否则返回-1值 for(int q=0;q5;q+) if(strcmp(keywordq,strtoken)=0) return q; if(q=4) return -1; void retract()/将搜索指示器回调一个字符位置,将ch置为空白字符 k-; ch=null; char*insertid()/将strtoken中的标识符插入符号表,返回符号表的指针 chr_formj=strtoken; j+; return chr_f

21、orm0; char * insertconst()/将strtoken中的常数插入常数表,返回常数表指针 int_formt=strtoken; t+; return int_form0; int code; / void output(int a,char *p1,char *p2)coutt类别码(class):at 单词值(value):;while(p1=p2)cout*p1;p1+;coutendl; void analyze() getchar(); getbc(); /cout此处没有错endl; if(isletter() while(isletter()|isdigit()

22、 concat(); getchar(); /cout此处没有错endl; retract(); code=reserve(); switch(code) case 0:cout需检测的的单词:strtoken 类别码为: begin endl;break; case 1:cout需检测的的单词:strtoken 类别码为: endendl;break; case 2:cout需检测的的单词:strtoken 类别码为: ifendl;break; case 3:cout需检测的的单词:strtoken 类别码为: thenendl;break; case 4:cout需检测的的单词:strt

23、oken 类别码为: elseendl;break; default: cout需检测的的单词:strtoken 类别码为: idendl;break; else if(isdigit() while(isdigit()|ch=.) concat(); getchar(); retract(); cout需检测的的单词:strtoken 类别码为: intendl; else switch (ch) case +: cout需检测的的单词:+ 类别码为: plendl;break; case-: cout需检测的的单词:- 类别码为: miendl;break; case*: cout需检测的

24、的单词:* 类别码为: muendl;break; case/: cout需检测的的单词:/ 类别码为: diendl;break; case:getchar(); if(ch=) cout需检测的的单词:= 类别码为: isendl;break; else retract(); cout需检测的的单词为非法输入!endl;break; case=:cout需检测的的单词:= 类别码为: eq:getchar();switch(ch) case=: cout= 类别码为: geendl;break; default:retract(); cout 类别码为: gtendl;break; cas

25、e:getchar(); switch(ch) case=:cout需检测的的单词:= 类别码为: le:cout需检测的的单词: 类别码为: neendl;break; default:retract(); cout需检测的的单词: 类别码为: ltendl;break; while(kq) for(int p=0;p50;p+) strtokenp=0; i=0; analyze(); void main() cout请输入一段程序,以#号结束:endl; form0=cin.get(); for( q=1;formq-1!=#;q+) formq=cin.get(); if(formq=

26、#) cout你输入的程序段为n; cout.write(form,q); break; coute(自己添加的)e-e+t| e-t|tt-t*f| t/f|ff-(e)|i该表1是根据下一页的图画出来的:+-*/()i#e t f0s4s51231s6s7acc2r3s8s9r3r33r6r6r6r6r6r64s4s510235r8r8r8r8r8r86s4s51137s4s51238s4s5139s4s51410s6s7s1511r1r1s8s9r1r112r2r2s8s9r2r213r4r4r4r4r4r414r5r5r5r5r5r515r7r7r7r7r7r7表1(2)对实验一得字符

27、串1.5e+2+100*555进行验证:经过自己的推理所得的表2步骤状态栈符号栈输入串actiongoto10#i+i*is5205#i+i*i#r8goto0,f=3303#f+i*i#r6goto0,t=2402#t+i*i#r3goto0,e=1501#e+i*i#s66016#e+i*i#s570165#e+i*i#r8goto0,f=380163#e+f*i#r6goto0,t=290162#e+t*i#s81001628#e+t*i#s511016285#e+t*i#r8goto0,f=312016283#e+t*f#r6goto0,t=21301611#e+t#r1goto0,e

28、=11401#e#acc成功!表2程序设计:(1)设置输入缓冲区用结构buf实现输入字符的存储,包括值和类型的存储(为实验三做准备),为后续的语法分析和词法分析做准备(2)状态栈state 作为状态栈,存储归约和移进过程状态的变化(3)符号栈symbol作为符号栈,栈顶的符号不断地进行着归约和移进的动作(4)运用c语言编写了相应的程序进行移近和归约以及接受的动作,需要注意的是,在规约的过程中不仅需要弹出数目确定的字符,还要有相应的字符入栈注意:在实验设计过程中,从读取存有算数字符的文件开始,就获得了每一个算术表达式的字符个数(除去”-”的剩余部分)并存储在数组vnum中三、 源程序代码实验代码

29、部分将会在实验三给出四、 实验结果见实验三实验三 语义分析程序实现李晓萌 088330一、实验内容:通过设计、编制、调试一个简单的语义处理分析程序,实现对实验一和实验二所得单词和语句的语义信息简单处里,进一步掌握语义处理的内容和简单方法。二、设计部分(1)需要将实验一的1.5e+2+100*555中的每一个无符号数相应的算出最终的结果:如:1500.000000+2.000000+100.000000*555.000000(2)在进行归约的过程中,不仅仅是弹出需要进行归约的字符,还要进行值的传递和计算计算(3)设计思路:1 calculate_unsignedfigure(char *p1,c

30、har *p2) 函数能过准确的计算出无符号的值2 quarternary_out(int a1,double a2,double a3,double a4)语义分析四元式输出3 store_resuctionmax在语法分析的过程中,把归约过程都标记在这个数组中& unsignedfigure在计算的过程中也已经把相应的算数字符的值存储在这个数组4调用相应的归约过程,利用unsignedfigure存储的值进行计算,最后获得运算结果结果可以对实验二得标进一步完善步骤状态栈符号栈输入串actiongoto语义处理生成中间代码10#i+i*is5205#i+i*i#r8goto0,f=3i1.v

31、alue=1500.000000303#f+i*i#r6goto0,t=2f1.value=1500.000000402#t+i*i#r3goto0,e=1t1.value=1500.000000501#e+i*i#s6e1.value=1500.0000006016#e+i*i#s570165#e+i*i#r8goto0,f=3i2.value=100.00000080163#e+f*i#r6goto0,t=2f2.value=100.00000090162#e+t*i#s8t2.value=100.0000001001628#e+t*i#s511016285#e+t*i#r8goto0,f

32、=3i3.value=555.00000012016283#e+t*f#r6goto0,t=2f3.value=100.000000(*,t2,f3,q1)1301611#e+t#r1goto0,e=1q1.value=55500.000000(+,q1,e1,q2)1401#e#acc成功!q2.value=55650.000000由此表可以看出,最终的结果因该是55650.000000三、 源程序代码#include #include#include #define max 100#define unsignednumber 1#define plus 2#define subtract

33、3#define multiply 4#define divide 5#define leftbracket 6#define rightbracket 7#define inefficaciouslabel 8#define finish 111/词法分析定义的部分int count=0;/记录类型的13145int count1=0;/词法分析结果缓冲表int class;int type100;char store20=0;double result=0.0;/词法分析的缓冲区struct aaint type;double value;buf1000;struct aa oth;/*_

34、语法分析定义的部分_*/char input20;/存放类别码转化的字符char store_grammar2010=0;/用来存放语法分析产生式char v_t10,v_n10;char avt8=+,-,*,/,(,),i,#;char gvn3=e,t,f;int vnnum,vtnum,statenum=16;int vnum10;int grammarnum;typedef structchar *base;char *top;symbolstack;typedef structint *base;int *top;statestack;statestack state;symbol

35、stack symbol;/*_词法分析子函数部分_*/bool tag=false;void storetype();void showstrfile();void output(int a,char *p1,char *p2);int sign(char *p);int unsignednum(char *p);int legalcharacter(char *p);void distinguishsign(char *p);void typydistinguish();void showtype();/语法分析子函数void changstyle();/*_语义分析的相关函数_*/dou

36、ble calculatestackmax,*p_trcal;/定义计算数值用的计算栈和指向它的首地址的指针double unsignedfiguremax;/存放每个无符号数的值int num2=0;int num3=0;int num4=0;int num5=0;boolmark=true;int store_resuctionmax;/语义分析时的归约动作所用产生式代号栈/语法分析slr1表int action168=0,0,0,0,104,0,105,0,106,107,0,0,0,0,-1,-1,53,53,108,109,0,53,0,53,56,56,56,56,0,56,0,5

37、6,0,0,0,0,104,0,105,0,58,58,58,58,0,58,58,58,0,0,0,0,104,0,105,0,0,0,0,0,104,0,105,0,0,0,0,0,104,0,105,0,0,0,0,0,104,0,105,0,106,107,0,0,0,115,0,0,51,51,108,109,0,51,51,51,52,52,108,109,0,52,0,52,54,54,54,54,0,54,54,54,55,55,55,55,0,55,0,55,57,57,57,57,0,57,0,57;int goto163=1,2,3,0,0,0,0,0,0,0,0,0,1

38、0,2,3,0,0,0,0,11,3,0,12,3,0,0,13,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,;void showstrfile()file *fp_s;char ch;if(fp_s=fopen(a.txt,r)=null)printf(the file cannot open!); exit(0);elsech=fgetc(fp_s);while(ch!=eof)putchar(ch);ch=fgetc(fp_s);printf(n);void storestr() file *fp=fopen(a.txt,r);char str;

39、int i=0;while(!feof(fp)fscanf(fp,%c,&str);if(str=?)storei=0;break;storei=str;i+;storei=0;void showstore()int i;for (i=0;storei!=0;i+) printf(%c,storei);printf(n);void output(int a,char *p1,char *p2) printf(%3st%dt%st,class,a,value);while(p1=p2)printf(%c,*p1);p1+;/printf(n);double calculate_decimalpart(char *p1,char *p2)char *p_1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论