编译技术课程设计报告-词法分析、语法分析、中间代码生成_第1页
编译技术课程设计报告-词法分析、语法分析、中间代码生成_第2页
编译技术课程设计报告-词法分析、语法分析、中间代码生成_第3页
编译技术课程设计报告-词法分析、语法分析、中间代码生成_第4页
编译技术课程设计报告-词法分析、语法分析、中间代码生成_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

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

文档简介

1、精选优质文档-倾情为你奉上编译技术课程设计 班 级 学 号 姓 名 指导老师 年 月目 录 一、目的-2 二、任务及要求-2 三、实验环境-4 四、实现过程说明-4 1.词法分析器-4 (1)单词符号表-4 (2)数据结构-5 (3)函数说明-5 (4)流程图-6 2.语法分析器-6 (1)分析方法说明-6 (2)文法-6 (3)数据结构-7 (4)函数说明-7 3.中间代码生成器-10 (1)属性文法-10 (2)数据结构-11 (3)函数说明-11 (4)流程图-11 五、程序运行结果-12 六、总结-16一、目的<<编译技术>>是理论与实践并重的课程,而其课程设计

2、要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。二、任务及要求基本要求:1 词法分析器 产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内码值如下表:单词符号种别编码助记符内码值while1while¾if2if¾else3else¾switch4switch¾case5case¾标识符6id符号表入口地址常数7num常数表入口地址=8=¾

3、;+9+¾*10*¾*11*¾-12-¾/13/¾>14relopMT>=14relopME<14relopLT<=14relopLE=14relopEQ!=14relopUEQ;15;¾,16,¾(17(LB)17)RB对于这个小语言,有几点重要的限制:首先,所有的关键字(如ifwhile等)都是“保留字”。所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。例如,下面的写法是绝对禁止的: if(5)=x 其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。也就是说,对于关

4、键字不专设对应的转换图。但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。例如,一个条件语句应写为 if i>0 i= 1;而绝对不要写成 ifi>0 i=1;因为对于后者,我们的分析器将无条件地将ifi看成一个标识符。这个小语言的单词符号的状态转换图,如下图: 2 语法分析器 能识别由加+ 乘* 乘方* 括号()操作数所组成的算术表达式,其文法如下:EE+T|TTT*

5、F|FFP*F|PP(E)|i 使用的算法可以是:预测分析法;递归下降分析法;LR分析法等。3 中间代码生成器 产生上述算术表达式的中间代码(四元式序列)较高要求:1 扩充上述小语言的单词;2 增加语法分析器的功能,能识别条件语句和循环语句等;3 增加中间代码生成器的功能,能产生条件语句和循环语句等的中间代码(四元式序列)4 报错基础上增加错误信息;5 将中间代码翻译成汇编语言。三、实验环境开发环境VC+;Visual Studio;Java开发环境语言C;C+;C#;Java说明:课程设计可以使用任何一种语言工具,课程设计报告中请按照自己实际采用的开发工具及技术来写。四、实现过程说明1.词法

6、分析器(1)单词符号表单词符号种别编码助记符内码值while1while¾if2if¾else3else¾switch4switch¾case5case¾标识符6id符号表入口地址常数7num常数表入口地址=8=¾+9+¾+9+¾+=9+= ¾*10*¾*11*¾-12-¾/13/¾/=13/=¾>14relopMT>=14relopME<14relopLT<=14relopLE=14relopEQ!=14relopUEQ;15;&

7、#190;,16,¾(17(LB)17)RB!18!¾20¾20¾21¾21¾:22:¾' '24' '¾(2) 数据结构用words10存放构成单词符号的字符串,并且用于判断是否为关键字。flags500 存放单词符号的种别码。Number存放整数值,words存放标识符,关键字或者其他符号。cntnum按顺序存放读到的字符,为下面语义分析做准备。Status用于判断是否为关键字,1是,0不是。(3) 函数说明在Scan ()子函数中,先全部初始化,然后读一个字符,分析它是什么类型

8、:如果是字母类型,则接着往下读,直到读到非字母的字符,存入words10中,依次对比关键字表中的元素,如果相同,则将flags置为相应的种别码,如果全都扫描后没发现相同的关键字,则为普通的标识符,返回主函数输出。如果是数字类型,首先分析第一个符号,接着读下一个字符串,直到读到一个不是数字的字符串位置,每读一个数字字符,就将他们转化为相应的数字,使用辗转相乘法,每次都让number先自乘10,然后加上这个数字,这样就将字符串表示的数字转化成了相应的数,返回主函数输出。如果是其他单词表的符号,则将他们的flags置为相应的种别码,并将字符存到words 中返回主函数输出。(4) 流程图 2.语法分

9、析器(1)分析方法说明 采用递归下降分析法(2) 文法EE+T|E-T|TTT*F|E/F|FFP*F|PP(E)|i改造后的文法ETE|TEE+TE|E-TE|TFT|FTT*FT|T/FT|FPFF*F|P(E)|i(3)数据结构与函数说明 在main函数调用E()函数,如果调用之后返回时,如果(flagstemp=0)&&is_right)为真,就输出“分析成功”,否则输出“分析失败”。其中is_right为设定的标志,初值为1,如果在调用子函数的过程中如果有错误,则置is_right为0。 E函数: 调用T函数,调用F函数, 调用P函数,返回后看是否是+或-,如果是,则

10、调用 E1函数,再调用E2函数,如果不是,进行出错处理,置is_right为0。 E1函数:判断是不是”+”或者“-” 如果是,调用F函数,如果不是,进行出错处理,置is_right为0。代码:void E()cout<<"E->TE''"<<endl;T();E2();void E1()if(flagstemp=9) /加号cout<<"E'->+T"<<endl;temp+;T();else if(flagstemp=12)/减号cout<<"E

11、'->-T"<<endl;temp+;T();elseis_right=0;void E2()if(flagstemp=9|flagstemp=12)/如果是加或减cout<<"E''->E'E''"<<endl; E1(); E2();else if (flagstemp!=0|flagstemp!=17)/如果是非#或非 cout<<"E''->"<<endl; return ; elseis_rig

12、ht=0; T函数: 调用F函数, 调用P函数,返回后看是否是*或/,如果是,则调用T1函数,再调用T2函数,如果不是,进行出错处理,置is_right为0。 T1函数:判断是不是”*”或者“/” 如果是,调用F函数,如果不是,进行出错处理,置is_right为0。代码:void T()cout<<"T->FT''"<<endl;F();T2();void T1()if(flagstemp=10) /乘号cout<<"T'->*F"<<endl;temp+;F();els

13、e if(flagstemp=13) /除号cout<<"T'->/F"<<endl;temp+;F();else is_right=0;void T2()if(flagstemp=10|flagstemp=13)/如果是乘或除cout<<"T''->T'T''"<<endl;T1();T2();else if (flagstemp!=0|flagstemp!=17)/如果是非#或非) cout<<"T''-&

14、gt;"<<endl; return ; else is_right=0; F函数:调用P函数,F1函数。 F1函数:判断是不是”*”,如果是,调用F函数,如果不是,进行出错处理,置is_right为0。代码:void F()cout<<"F->PF'"<<endl;P(); F1();void F1() if(flagstemp=11) /乘?方? cout<<"F'->*F"<<endl;temp+;F(); Elseif(flagstemp!=0&am

15、p;&flagstemp!=17&&flagstemp!=9&&flagstemp!=12&&flagstemp!=10&&flagstemp!=13)/非#非)非+非-非*非/ cout<<"F'->?"<<endl;is_right=0; P函数: 检查是否标识符,如果是,调用P1函数,如果不是,检查是否是数值,如果是,调用P1函数,如果不是,检查是否是(,如果不是,进行出错处理,置is_right为0。如果是,调用E函数,返回后检查是否是),如果不是,进行出错

16、处理,置is_right为0。如果是,调用F1函数,返回。代码:void P()if(flagstemp=6|flagstemp=7) /标识符或常数cout<<"P->i"<<endl;temp+;else if(flagstemp=17) /(cout<<"P->(E)"<<endl;temp+;E();if(flagstemp=17) /)cout<<"P->(E)"<<endl;temp+;elseis_right=0;else is_r

17、ight =0;3.中间代码生成器(1)属性文法 EE+T E.val=E.val+T.valEE-T E.val=E.val-T.valET E.val=T.valTT*F T.val=T.val*F.valTT/F T.val=T.val/F.valTF T.val=F.valFP*F F.val=P.val*F.valFP F.val=P.valP(E) P.val=E.valFi F.val=i,lexval(2)数据结构与函数说明Strn用来存放临时变量的序号。temp用来存放数组的下表,在主程序中语法分析结束后,置0.定义函数newtemp()用于门生一个新的临时变量的名字,具体实

18、现时每产生一个T,就及时送到符号表中,也可以不进符号表,直接将单词值用整数码表示。定义函数siyuan(),输出一个四元式。定义函数YE() 进行中间代码生成(3)流程图 5、 程序运行结果注:本程序对于形如a1的标识符无法作为整体识别词法测试:表达式正确:2*3+4/(as-5)*6#词法分析:语法分析四元式: 表达式错误:2*(3-2#六、总结这次课程设计使我对编译原理有了进一步的了解,更加巩固了所学习的知识。编译原理是一门比较抽象的课程,也比较难以学得透,有很多东西很模糊的。编译这个概念有一定的了解。由于课堂上,学习的东西比较浅,难免眼高手低,故而,通过实验和课程,遇到了很多课本上面见不

19、到的问题,完成实验后,个人在成就感的同时,也学习到了编程的具体过程中的很多知识。程序代码:/#include <stdafx.h>#include <iostream>#include<string>using namespace std;#include<stdio.h>#include<stdlib.h> #include<sstream>int i,j,k,flag,number,status;/*status which is use to judge the string is keywords or not!*

20、/char ch;char words10 = " "char program500;int flags500; /存储输入句子string cnt500;/标括识符int temp=0; /数组下标int is_right; /判断输出信息/-词法分析-int Scan(char program) char *keywords5 = "while","if","else","switch","case" /关键字number=0;status=0;j=0;ch=progra

21、mi+; /遍历if (ch >= 'a') && (ch <= 'z' )|(ch>='A')&&(ch<='Z') /字母 while (ch >= 'a') && (ch <= 'z' )|(ch>='A')&&(ch<='Z') wordsj+=ch; ch=programi+; i-; wordsj+ = '0'for (k = 0

22、; k < 5; k+)if (strcmp (words,keywordsk) = 0) /判断是否为关键字switch(k)case 0:flag = 1;status = 1;break;case 1:flag = 2;status = 1;break;case 2:flag = 3;status = 1;break;case 3:flag = 4;status = 1;break;case 4:flag = 5;status = 1;break;if (status = 0)flag = 6; /标识符else if (ch >= '0') &&am

23、p; (ch <= '9') /数字 number = 0; while (ch >= '0' ) && (ch <= '9' ) number = number*10+(ch-'0'); ch = programi+;flag = 7;i-;else switch (ch) /运算符和标点符号case '=': if (ch = '=') wordsj+ = ch; wordsj = '0' ch = programi+; if (ch = 

24、9;=') wordsj+ = ch; wordsj = '0' flag = 14; else i-; flag = 8; break; case'>': if (ch = '>') wordsj+ = ch; wordsj = '0' ch = programi+; if (ch = '=') wordsj+ = ch; wordsj = '0' flag =14; else i-; flag = 14; break; case'<': if (ch =

25、 '<')wordsj+ = ch;wordsj = '0'ch = programi+;if (ch = '=')wordsj+ = ch;wordsj = '0'flag = 14;elsei-;flag = 14;break;case'!':if (ch = '!')wordsj+ = ch;wordsj = '0'ch = programi+;if (ch = '=')wordsj+ = ch;wordsj = '0'flag = 14;

26、elsei-;flag = 18;break;case'+':if (ch = '+')wordsj+ = ch;wordsj = '0'ch = programi+;if (ch = '=')wordsj+ = ch;wordsj = '0'flag = 9;else if (ch = '+')wordsj+ = ch;wordsj = '0'flag = 9;elsei-;flag = 9;break;case'-':if (ch = '-')wo

27、rdsj+ = ch;wordsj = '0'ch = programi+;if (ch = '=')wordsj+ = ch;wordsj = '0'flag = 12;else if( ch = '-')wordsj+ = ch;wordsj = '0'flag = 12;elsei-;flag = 12;break;case'*':if (ch = '*')wordsj+ = ch;wordsj = '0'ch = programi+;if (ch = '

28、;*')wordsj+ = ch;wordsj = '0'flag = 11;elsei-;flag = 10;break;case'/':if (ch = '/')wordsj+ = ch;wordsj = '0'ch = programi+;if (ch = '=')wordsj+ = ch;wordsj = '0'flag = 13;elsei-;flag = 13;break;case'':wordsj = ch;wordsj+1 = '0'flag

29、= 15;break;case'(':wordsj = ch;wordsj+1 = '0'flag = 17;break;case')':wordsj = ch;wordsj+1 = '0'flag = 17;break;case'':wordsj = ch;wordsj+1 = '0'flag = 21;break;case'':wordsj = ch;wordsj+1 = '0'flag = 21;break;case'':wordsj = ch;

30、wordsj+1 = '0'flag = 20;break;case'':wordsj = ch;wordsj+1 = '0'flag = 20;break;case':':wordsj = ch;wordsj+1 = '0'flag = 22;break;case',':wordsj = ch;wordsj+1 = '0'flag = 16;break;case'#':wordsj = ch;wordsj+1 = '0'flag = 0;break;

31、case' ':/空格 wordsj ='_' wordsj+1 = '0' flag = 24; break;/case'$':/wordsj = '#'/wordsj+1 = '0'/flag = 0;/break;/default:flag = -1;break;return flag;/-语法分析(递归下降)-void E();void E1();void E2();void T(); void T1();void T2();void F();void F1();void P();void

32、E()cout<<"E->TE''"<<endl;T();E2();void E1()if(flagstemp=9) /加号cout<<"E'->+T"<<endl;temp+;T();else if(flagstemp=12)/减号cout<<"E'->-T"<<endl;temp+;T();elseis_right=0;void E2()if(flagstemp=9|flagstemp=12)/如果是加或减co

33、ut<<"E''->E'E''"<<endl; E1(); E2();else if (flagstemp!=0|flagstemp!=17)/如果是非#或非) cout<<"E''->"<<endl; return ; elseis_right=0;void T()cout<<"T->FT''"<<endl;F();T2();void T1()if(flagstemp=10

34、) /乘号cout<<"T'->*F"<<endl;temp+;F();else if(flagstemp=13) /除号cout<<"T'->/F"<<endl;temp+;F();else is_right=0;void T2()if(flagstemp=10|flagstemp=13)/如果是乘或除cout<<"T''->T'T''"<<endl;T1();T2();else if (

35、flagstemp!=0|flagstemp!=17)/如果是非#或非) cout<<"T''->"<<endl; return ; else is_right=0;void F()cout<<"F->PF'"<<endl;P(); F1();void F1() if(flagstemp=11) /乘方 cout<<"F'->*F"<<endl;temp+;F(); else if (flagstemp!=0&am

36、p;&flagstemp!=17&&flagstemp!=9&&flagstemp!=12&&flagstemp!=10&&flagstemp!=13)/非#非)非+非-非*非/ cout<<"F'->"<<endl;is_right=0; void P()if(flagstemp=6|flagstemp=7) /标识符或常数cout<<"P->i"<<endl;temp+;else if(flagstemp=17)

37、 /(cout<<"P->(E)"<<endl;temp+;E();if(flagstemp=17) /)cout<<"P->(E)"<<endl;temp+;elseis_right=0;else is_right =0;/-语义分析以及中间代码生成-int YE();int TE1(int a);int YE2(int a);int YT();int YT1(int a);int YT2(int a);int YF();int YF1(int a);int YP();int v=-1;int

38、 num=0;int ww;string strn;int nn;int newTemp()num+;nn+; stringstream stream;stream<<nn;stream>>strn;stream.clear();cntnum-1="temp" cntnum-1.operator+=(strn);/把字符串s连接到当前字符串的结尾 /cntnum-1=strcat("Temp",strn); / cntnum-1="temp"return num-1;void siyuan(int a,int

39、b,int c,int d)/输出四元cout<<"("<<cnta<<","<<cntb<<","<<cntc<<","<<cntd<<")"<<endl;int YE()int rt,t1;rt=YT();t1=rt;rt=YE2(t1);return rt;int YE1(int a)int rt,t1;t1=a; if(flagstemp=9) /加法temp+;int

40、 tt=v+1;v+;int t2=YT();int rr=newTemp();siyuan(tt,t1,t2,rr);rt=rr;return rt;else if(flagstemp=12) /减法temp+;int tt=v+1;v+;int t2=YT();int rr=newTemp();siyuan(tt,t1,t2,rr);rt=rr;return rt;else return t1;int YE2(int a)int rt,t1;t1=a;if(flagstemp=9|flagstemp=12)/+或- rt=YE1(t1); t1=rt; rt=YE2(t1); return

41、 rt; else if (flagstemp!=0|flagstemp!=17) return t1; else return t1;int YT()int rt,t1;rt=YF();t1=rt;rt=YT2(t1);return rt;int YT1(int a)int rt,t1;t1=a;if(flagstemp=10) /乘法int tt=v+1;v+;temp+;int t2=YF();int rr=newTemp();siyuan(tt,t1,t2,rr); rt=rr;return rt;else if(flagstemp=13) /除法temp+;int tt=v+1;v+

42、; int t2=YF();int rr=newTemp();siyuan(tt,t1,t2,rr);rt=rr; return rt;else return t1;int YT2(int a)int rt,t;t=a;if(flagstemp=10|flagstemp=13)/乘或除rt=YT1(t);t=rt; rt=YT2(t);return rt;else return t;int YF()int t1,rt; rt=YP();t1=rt; rt=YF1(t1); return rt;int YF1(int a) /乘方int rt,t1;t1=a; if(flagstemp=11)t

43、emp+;int tt=v+1;v+;int t2=YF();int rr=newTemp();siyuan(tt,t1,t2,rr);rt=rr;return rt;else return t1;int YP()int rt,t1;if(flagstemp=6|flagstemp=7)/标识符或常数v+;rt=v; temp+; return rt;else if(flagstemp=17) /(v+; temp+; rt=YE();if(flagstemp=17) /)v+; temp+;return rt;else return ww;else return ww;void main()

44、 printf(" -单词号对应的种别编码-n"); printf("n"); printf("(while,1) (if,2) (else,3) (switch,4) (case,5)n"); printf("n"); printf("(标括识符,6) (常数,7) (=,8) (+,9) (+,9)n"); printf("n"); printf("(+=,9) (*,10 ) (*,11) (-,12) (/,13)n"); printf("n"); printf("(/=,13) (>,14) (>

温馨提示

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

评论

0/150

提交评论