中间代码生成实验报告_第1页
中间代码生成实验报告_第2页
中间代码生成实验报告_第3页
中间代码生成实验报告_第4页
中间代码生成实验报告_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

1、精选优质文档-倾情为你奉上 一 、 实验目的 通过在实验二的基础上,增加中间代码生成部分,使程序能够对实验二中的识别出的赋值语句,if语句和while语句进行语义分析,生成四元式中间代码。二 、 实验方法 实验程序由c语言完成,在Turboc 2.0环境中调试通过。 语义分析程序的基本做法是对文法中的每个产生式分别编写一个语义分析子程序,当程序语法部分进行推倒或规约时,就分别调用各自的语义分析程序。当语法分析结束时,语义分析也就结束了。 在本实验程序中,当语法分析部分识别出语法正确的句子时,就进入content函数(当语法分析识别出不正确的句子时,不进入content函数,也就是不进行语义分析

2、),然后根据句子的类型进行分类,进入不同的语义处理部分。 对于赋值语句,关键是产生正确的处理算术表达式E的四元式。程序中的ec函数的功能就是产生算术表达式的四元式,在ec函数中使用了两个栈idshed,opshed,分别是算术表达式的数据栈和符号栈。每次提取一个数字和一个算符,然后将算符与与栈顶算符进行优先级比较,优先级高则将单前数字和算符进栈,低或者相等的话则将当前栈顶元素进行合并,产生四元式。直至整个算术表达式结束。其中还有一些细节问题,具体的做法可以参看程序。 对于实验给定的if语句的文法格式,条件判断式C只中可能是>或者<=两种关系,不可能是布尔表达式,这样程序就简单的多了

3、。通过ec函数可以产生条件判断式C中的E的四元式,然后只要加上转向四元式就可以了。本实验程序中只给出真出口的转向四元式,没有给出假出口的转向四元式,这在实际中是不可以的,但在本实验中,实际上是对每条独立的语句进行语法分析,给出假出口转向四元式实际上意义不大,而且假出口转向语句的转移目标必须要到整个语句分析结束以后才可以知道,这样就要建立栈,然后回填,这样会使程序复杂很多,所以没有加上假出口转向四元式。 对于while语句,具体的做法和if语句差不多,所不同的是当while语句结束时,要多出一条无条件转向四元式,重新转到条件判断式C的第一条四元式。当要产生无条件转向四元式时,它的转向目标C的第一

4、条四元式已经产生了,所以具体的做起来是不太困难的。只要记下当前while中的C的第一条四元式的位置,填上就可以了。 整个程序的结束是当读入“ . ”时,程序就中止。 程序中还有很多细节问题,具体的可以后面的附录:程序的完整代码。三 、 测试程序 ff:=6+6*6-; if sl>89+56*67 then f:=7*7+4; ff:=6+6*6-6%4+8; if sl+78*76>89*56+67 then while a-7>98+45*45 do f:=7*7+4; . 四 、 运行结果 首先对测试程序进行语法分析,识别出正确的句子,当识别出正确的句子时,就对当前句子

5、进行语义分析,而语法不正确的句子不进行语义分析。ff:=6+6*6- Error(4):Except ID or NUM ; Error(2):Syntax error if sl>89+56*67 then f:=7*7+4; success!(1) *, 56, 67, T1 (2) +, 89, T1, T2 (3) j>, sl, T2, (4) (4) *, 7, 7, T3 (5) +, T3, 4, T4 (6) :=, T4, -, f ff:=6+6*6-6%4+8; success!(7) *, 6, 6, T5 (8) +, 6, T5, T6 (9) %,

6、6, 4, T7 (10) -, T6, T7, T8 (11) +, T8, 8, T9 (12) :=, T9, -, ff if sl+78*76>89*56+67 then while a-7>98+45*45 do f:=7*7+4; success!(13) *, 78, 76, T10 (14) +, sl,T10, T11 (15) *, 89, 56, T12 (16) +,T12, 67, T13 (17) j>, T11, T13, (18) (18) -, a, 7, T14 (19) *, 45, 45, T15 (20) +, 98,T15, T1

7、6 (21) j>, T14, T16, (22) (22) *, 7, 7, T17 (23) +,T17, 4, T18 (24) :=, T18, -, f (25) j, _, _, (18). Error(2):Syntax error 五 、 实验小结 终于完成了编译原理的三次实验,这几次实验使我们更彻底地巩固了编译原理。从詷法分析到语法分析直到这次的中间代码都是看似简单的基础知识,却花了不少时间对课本多次反复研究、请教学习,进行深层次地探讨才找出编程时出现的种种问题。还有很多程序方面很细节的问题,很容易被突略,却往往又是关键。 总地来说,虽然实验做得很辛苦,但真的可以从实验

8、当中学习到很多,认识到很多。并对编译理解也透彻了许多,比较清晰地掌握了编译程序的原理和方法。 附录: #include<string.h>#include<stdio.h>#include<stdlib.h> #define reser 20 char *charstring="abcdefghijklmnopqrstuvwxyz" char *numstring="" char *strstring="abcdefghijklmnopqrstuvwxyz" char reservereser10;

9、 char idshed4010,opshed4010; char token15,id15,sym15; char line80,tempp240; char ch,ch1,temp,tem; char tx10; char tn4,signt120,signt220,ju20; int cc,ii,k,num,kind,t,e4=0,e3=0,judge=1,row1=0; int startc,idsh=0,opsh=0,tt=1,nn=1,signwh,over=0,adds=0,whs=0,pp=0; int li=0; char filename15; FILE *fp;void

10、getch() if(li=0) if (cc=ii) cc=1; ii=0; if (row1=1) fseek(fp,-1,1); /*读行首字符将指针退回一格,若是整个文本的开头,则不需要*/ line0=fgetc(fp); row1=1; while(temp=fgetc(fp)!='n') && (temp!=EOF) linecc=temp;cc+; tempppp=temp;pp+; linecc=' ' /*将缓冲带后加上一个空字符,以便行和行之间号区分 */ cc+; tempppp=' ' pp+; whil

11、e(temp=fgetc(fp)='n') && (temp!=EOF); /* 跳过空行*/ linecc='0' tem=lineii; ii+; ch=tem; else ch=tempppp; pp+; void getnbc()getch();while (ch=' ') getch(); if (ch='') do getch(); while( ch=''); getnbc(); void retract() ii-; void ret() pp-;int jchar(char ch)

12、 /* 判断ch是不是字母 */if(strchr(charstring,ch)=0) return 0; else return 1;int jnum(char ch) /* 判断ch是不是数字 */if(strchr(numstring,ch)=0) return 0; else return 1;int jstr(char ch) /* 判断ch是不是字母或数字 */if(strchr(strstring,ch)=0) return 0; else return 1;void advance() getnbc(); kind=0; if (jchar(ch)=1) k=0; do if(

13、k<15) tokenk=ch; k+;getch(); while(jstr(ch)=1); if (li=0) retract(); else ret(); tokenk='0' /*截去token中的无用字符*/ strcpy(id,token); for(t =0;t<=20;t+) if(strcmp(reservet,id)=0) break; if ( t<=20 ) kind=t ; else kind=21; strcpy(sym,id); else if (jnum(ch)=1) k=0;do if ( k<15 ) tokenk=c

14、h; k+; getch(); while( jstr(ch)=1); if (li=0) retract(); else ret();kind=22;tokenk='0'strcpy(sym,token); else if(ch='.') kind=26; k=0; do symk=' ' k+; while(k!=15); sym0=ch; sym1='0' void error(int n) judge=0; /*出错退出,将judge0*/ switch(n) case 0:printf(" Error(0):E

15、xpect ':' n"); break; case 1:printf(" Error(1):Expect '=' n"); break; case 2:printf(" Error(2):Syntax error n");break; case 3:printf(" Error(3):Except Operater n");break; case 4:printf(" Error(4):Except ID or NUM n");break; case 5:printf(&

16、quot; Error(5):Except '' n");break; case 6:printf(" Error(6):Except '<' or '>'n");break; case 7:printf(" Error(7):Except '=' n" );break; case 8:printf(" Error(8):Except 'then' n");break; case 9:printf(" Error(9):Ex

17、cept Condition Expressionn ");break; case 10:printf(" Error(10):Except 'do' ");break; default: ; void e() advance(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strcmp(sym,"%")=0) printf("%s",sym); advance();

18、 if(kind=21) | (kind=22) /* kind为21,22分别表示的是标志符和数字 */ printf("%s",sym); e(); else e4=1 ;error(4); /*出错退出,e4=1*/ void c() advance(); if(kind=21) | (kind=22) printf("%s",sym); e(); if(e4=1); /*e4的作用是判断程序从e()中是不是出错退出*/else if(strcmp(sym,">")=0) printf("%s",sym

19、); advance(); if(kind=21) | (kind=22) printf("%s",sym); e(); elseerror(4); else if(strcmp(sym,"<")=0) printf("%s",sym); advance();if(strcmp(sym,"=")=0) printf("%s",sym); advance(); if(kind=21) | (kind=22) printf("%s",sym); e();elseerror(

20、4); elseerror(7); elseerror(6); elsee3=1; error(9); /*出错退出,e3=1*/ void statement() if(judge=1) /*judge的作用为判断程序是不是出错退出,若是,则无需advance()*/ advance(); switch (kind) case 21: /* id */ printf("%s",sym); advance(); if(strcmp(sym,":")=0) printf("%s",sym);advance(); if(strcmp(sy

21、m,"=")=0) printf("%s",sym); advance(); if(kind=21) | (kind=22) printf("%s",sym); e(); if(e4=1) ; else if(strcmp(sym,"")=0) printf("%s",sym); judge=1; printf(" success!n"); startc=1; else error(5); e4=0; /*将e4重新置为0,以免对下面程序有影响*/ else error(4)

22、; else error(1); else error(0); break; case 8: printf("%s ",sym); /* if */ c(); if(e4=1); else if(e3=1); /*e3的作用是判断程序从c()中是不是出错退出*/ else if(strcmp(sym,"then")=0)printf(" %s ",sym); statement(); elseerror(8); e3=0; /*将e3重新置为0,以免对下面程序有影响*/ e4=0; break; case 19: /* while *

23、/ printf("%s ",sym); c(); if(e4=1); else if(e3=1); else if(strcmp(sym,"do")=0)printf(" %s ",sym); statement(); elseerror(10); e3=0; e4=0; break; default: printf("%s ",sym);error(2); judge=1; break; void pushid()strcpy(idshedidsh,sym);idsh+; void pushop() strcp

24、y(opshedopsh,sym); opsh+; void gen(char op10,char a10,char b10) printf("(%d) %2s,%3s,%3s, T%d n",nn,op,a,b,tt);tt+;nn+; itoa(tt-1,tn,10); strcpy(tx,"T"); strcat(tx,tn); void ec() advance(); pushop(); advance(); pushid(); if(strcmp(opshedopsh-1,"*")=0)|(strcmp(opshedopsh

25、-1,"%")=0) gen(opshedopsh-1,idshedidsh-2,idshedidsh-1);opsh-;idsh=idsh-1;strcpy(idshedidsh-1,tx); else if(strcmp(opshedopsh-1,"+")=0)|(strcmp(opshedopsh-1,"-")=0) adds=1;if(strcmp(opshedopsh-2,"+")=0)|(strcmp(opshedopsh-2,"-")=0) gen(opshedopsh-2,ids

26、hedidsh-3,idshedidsh-2);strcpy(idshedidsh-2,tx); advance(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strc mp(sym,"%")=0) if (li=0) retract(); else ret(); ec(); void content() int reu; reu=nn; switch(kind) case 21:advance();advance();advan

27、ce();pushid(); advance(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strcmp(sym,"%")=0) if (li=0) retract(); else ret();ec(); if (adds=1) gen(opshedopsh-1,idshedidsh-2,idshedidsh-1); adds=0; printf("(%d) :=, %s, -, %s n",nn,tx,ids

28、hed0); nn+; idsh=0; opsh=0; else printf("(%d) :=, %s, -, %s n",nn,idshed1,idshed0); nn+;break; case 8: idsh=0; opsh=0;advance();pushid(); advance(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strcmp(sym,"%")=0) if (li=0) retract()

29、; else ret(); ec(); if(adds=1) gen(opshedopsh-1,idshedidsh-2,idshedidsh-1);adds=0; strcpy(signt1,tx); idsh=0; opsh=0; else strcpy(signt1,idshed0); if(strcmp(sym,">")=0) strcpy(ju,"j>"); else strcpy(ju,"j<="); advance(); idsh=0; opsh=0; advance(); pushid(); adva

30、nce(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strcmp(sym,"%")=0) if (li=0) retract(); else ret(); ec(); if (adds=1) gen(opshedopsh-1,idshedidsh-2,idshedidsh-1); adds=0; strcpy(signt2,tx); idsh=0; opsh=0; else strcpy(signt2,idshed0); pri

31、ntf("(%d) %s, %s, %s, (%d) n",nn,ju,signt1,signt2,nn+1); nn+; advance(); idsh=0; opsh=0; if(kind=21) pushid(); content();break; case 19: idsh=0; opsh=0;advance();pushid(); advance(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strcmp(sym,"%")=0) if (li=0) retract(); else ret();ec(); if(adds=1) gen(opshedopsh-1,idshedidsh-2,idshedidsh-1);adds=0; strcpy(signt1,tx); idsh=0; opsh=0; else strcpy(signt1,idshed0); if(strcmp(sym,">")=0) strcpy(ju,

温馨提示

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

评论

0/150

提交评论