编译原理课程设计报告_第1页
编译原理课程设计报告_第2页
编译原理课程设计报告_第3页
编译原理课程设计报告_第4页
编译原理课程设计报告_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

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

文档简介

1、编译原理课程设计报告 课 程 设 计 报 告 设计题目:一个简单文法的编译器的设计与实现 班 级:计算机1206班 组长学号:2012XXX 组长姓名:XXX 指导教师:XXX 设计时间:2014年12月 设计分工 组长学号及姓名:2012XXX XXX 分工:1)读取源文件进行词法分析 2)进行LL(1)分析生成分析表 3)设计顶层自动机将源程序分段 4)生成可执行的汇编程序 组员1学号及姓名:2012XXXXXX 分工:1)设计第二层自动机处理程序片段 2)生成中间语言四元式 3)源程序错误处理 组员2学号及姓名:2012XXXXXX 分工:1)设计第三层自动机处理复合表达式 2)设计带动

2、作的LL(1) 文法 3)源程序错误处理摘 要编译原理课程具有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,在系统软件中也是占有十分重要的地位。本次课程设计我们是在Visual C+的平台上应用了词法分析、语法分析、语义分析、中间语言生成以及目标语言生成的知识设计了一个简单的编译器前端。其中设计了一个简单的有限自动机来扫描源程序即进行语法分析,并生成了关键字表、标志符表、界符表、常数表和Token串;设计了一个LL(1)文法和一个带动作的文法来实现语法分析,并生成了Select集和LL(1)分析表;采用了四元式序列的设计来生成中间语言;通过汇编语言设计来生成目标语言。最后为了

3、使该编译器更加完善,我们设计了简单的的错误检查机制,能够对源程序进行比较全面的错误检查同时也能够指出错误出现的大致位置,增强了该编译器的健壮性。关键字:编译器,前端,有限自动机,LL(1)文法,汇编语言,错误处理目 录 摘要31、概述52、课程设计任务及要求52.1设计任务52.2设计要求63、算法与数据结构63.1词法分析器的算法63.2 语法分析器的算法12 3.2.1 LL(1)文法设计算法12 3.2.2递归下降子程序设计算法193.3中间语言生成器算法203.4处理复合表达式算法24 3.5目标语言生成器算法30 3.6数据结构394、程序设计与实现394.1编译程序设计与实现39

4、4.2程序实验结果39 4.2.1待测源程序39 4.2.2词法分析结果40 4.2.3语法分析结果41 4.2.4中间语言生成结果42 4.2.5目标语言生成结果43 4.2.6程序错误处理结果445、参考文献441、概述本次课程设计的编译程序主要包括了词法分析器、语法分析器、中间代码生成器和目标代码生成器四部分,编译程序的输出结果包括了词法分析后的关键字表、界符表、标识符表和Token串,语法分析后的Select集和LL(1)分析表;中间代码生成器产生的四元式序列。最后除了完成设计所要求的内容之外,我们还做了一些扩展例如:设计了目标代码生成器来生成可执行的汇编程序;还设计了错误检查机制来查

5、找源程序的错误并指出错误产生的大致位置。词法分析是编译程序的第一步操作,它的任务是:从左至右扫描源程序的字符串,按照一定的词法规则识别出一个个正确的字符,并转换成该字符相对应的Token码,最终生成一个完整的Token串以供语法分析使用。由此可知,词法分析是整个编译程序的基础,而执行词法分析的一系列操作的就是词法分析器。语法分析是编译程序的第二步操作也是编译程序的核心部分,其主要任务是:分析语法内容,确定语法结构同时生成Select集和LL(1)分析表。中间代码和目标代码的生成是对源程序的进一步操作,其任务是:根据词法分析产生的Token串和语法分析确定的语法结构来生成中间语言四元式和目标语言

6、汇编语言程序。2、课程设计任务及要求 2.1设计任务 一个简单文法的编译器前端的设计与实现l 定义一个简单程序设计语言文法(包括变量说明语句、算术运算表达式、赋值语句;扩展包括逻辑运算表达式、If语句、While语句等);l 扫描器设计实现;l 语法分析器设计实现;l 中间代码设计;l 中间代码生成器设计实现。 l 目标代码生成器设计实现 2.2设计要求l 给出一个源程序文件,作为编译器前端的输入l 输出相关编译阶段的运行结果l 词法分析阶段:l 生成Token序列;l 生成关键字表、界符表、符号表系统。l 中间代码生成阶段:l 生成四元式序列;l 生成符号表系统。3、 算法与数据结构 3.1

7、词法分析器的算法 1)一个简单有限自动机(扫描器)的设计:n?d-dd.dd-=-#-d 其中: (字母),d(数字),#(源程序结束符) (2)?(空格,回车,换行)需要滤掉 (3)(泛指单词的后继附) (4)(表示省略了其他界符的处理)2)一个简单词法分析器设计:开始结束调用识别器关键字/标识符算术常数结束符#查KT表查到查填IT表查填CT表常数处理C.TOKEN查PT表P.TOKENI.TOKENK.TOKENyn查到ere:非法界符ynyynnny 算法实现如下:Void main() /词法分析部分代码 char p10;string TOKEN;string Source;stri

8、ng temp;FILE* fp;fp=fopen(D:MySourceFile.txt,r);if(!fp) Source=Cannot open file;elseint i;char c;while(!feof(fp)c=fgetc(fp);Source+=c;fclose(fp);for(i=0;iSource.size();i+)if(Sourcei=13|Sourcei=9|Sourcei=10|Sourcei=-1)Source.replace(i,1, );Source+=#;cout处理后源程序nSourceendlendl;initKTPT();int i,j;for(i=

9、0;iSource.size();i+)switch(kindofchar(Sourcei)case e:coutn非法字符!,位置:i错误代码Sourceiendlendl;for(int k=0;k=i;k+) coutSourcek;exit(0);case s:break;case d:temp+=Sourcei;for(j=1;Sourcei+j=.|kindofchar(Sourcei+j)=d;j+) temp+=Sourcei+j;i=i+j-1;if(inCT(temp)=-1)temp=N +temp;CT.push_back(temp);TOKEN+=;temp=;bre

10、ak;case w:temp+=Sourcei;for(j=1;kindofchar(Sourcei+j)=w|kindofchar(Sourcei+j)=d|Sourcei+j=_;j+) temp+=Sourcei+j;i=i+j-1;if(inKT(temp)!=-1)TOKEN+=;temp=;break;if(inIT(temp)=-1) IT.push_back(temp);TOKEN+=;temp=;break;case f:temp+=Sourcei;if(kindofchar(Sourcei+1)=f&inPT(temp+Sourcei+1)=0)temp+=Sourcei+

11、1;i+;TOKEN+=;temp=;break;case :i+;for(j=0;Sourcei+j!=&(i+j)=(Source.size()-1)cout未找到可匹配的双引号,位置:iendl;for(int k=0;k=i;k+) coutSourcek;exit(0);i=i+j;if(inCT(temp)=-1)temp=S +temp;CT.push_back(temp);TOKEN+=;temp=;break;case :if(i+3)(Source.size()-1)&Sourcei+1=&Sourcei+3=)switch(Sourcei+2)case :temp+=;b

12、reak;case :temp+=;break;case :temp+=;break;case 0:temp+=0;break;default:cout错误的单引号使用(转义错误),位置:iendl;for(int k=0;k=i;k+) cout=(Source.size()-1)cout错误的单引号使用(越界),位置:iendl;for(int k=0;k=i;k+) coutSourcek;exit(0);temp+=Sourcei+1;i+=2;if(inCT(temp)=-1)temp=C +temp;CT.push_back(temp);TOKEN+=;temp=;break;ca

13、se #:break;default:break;3.2语法分析器的算法首先介绍一下整个课程设计中我们使用到的一些文法。C-文件 - void main ( ) C Y Y - S ; I| Z ; I| VNB I| W II-Y | 空S -类型 标识符 声明后继类型 - int|float|char声明后继 - ,标识符 声明后继 | 空Z - 标识符 = 表达式V - if ( E )C N-else C | 空W - while ( 表达式 )程序体E - 详见rull.txt源文件。语法分析主要是对LL(1)文法和递归下降子程序的设计,其算法设计如下:3.2.1 LL(1)文法的设

14、计1)算法原理如下:l 利用一个分析表,登记如何选择产生式的知识;l 利用一个分析栈,记录分析过程;l 此分析法要求文法必须满足 LL(1)文法形式。# Z开始:栈 ; NEXT(w)2) 算法设计如下: 重复执行 、 ,直到栈中只剩 # 为止: (1) (2) 若 栈顶符=A 且 当前符 w=a 且 有产生式: Aaa, 则 POP,PUSH(aa)R ; 若 栈顶符=a 且 当前符为a; 则 pop,NEXT(w); 否则,错误处理!#栈结束:;当前符 w= # (3)算法实现如下:void maketable()/需要参数指明所需文法/打开文件/switch()/根据参数选择文法FILE

15、* fp=fopen(D:/rull.txt,r);if(fp=NULL)cout打开文件失败endl;getchar();exit(0);/读取文件string source=;char readchar;doreadchar=fgetc(fp);source+=readchar;while(readchar!=EOF);fclose(fp);/cout-source流-endlsourceendl;/检查/从source流中提取有效数据Vs=source3;Vn+=Vs;int i,j,k,l;string ps=;for(i=8;sourcei!=;i+) Vn+=sourcei;i+=

16、4;for(;sourcei!=;i+) Vt+=sourcei;i+;while(sourcei!=;)for(;sourcei!= &sourcei!=;i+)ps+=sourcei;QRULL.push_back(ps);ps=;if(sourcei= ) i+;/拆分或符号string ps2=;int flag;for(i=0;iQRULL.size();i+)flag=0;for(j=0;j;for(j=0;QRULLij!=|;j+) ps+=QRULLij;for(j+;jQRULLi.length();j+) ps2+=QRULLij;QRULLi=ps;QRULL.push

17、_back(ps2);ps=;ps2=;cout-有效四元产生式表-endl;/检查for(i=0;iQRULL.size();i+)/检查coutQRULLi ;/检查coutendl;/检查/从四元产生式转化为普通产生式ps=;for(i=0;iQRULL.size();i+)k=0;ps=;for(j=0;jQRULLi.size();j+)if(QRULLij!=) ps+=QRULLij;else j+=2;RULL.push_back(ps);cout-有效普通产生式表-endl;/检查for(i=0;iRULL.size();i+)/检查coutRULLi ;/检查coutend

18、l;/检查/检测直接左递归flag=0;for(i=0;iRULL.size();i+)if(RULLi0=RULLi3) flag=1;if(flag=1)system(cls);system(color CF);cout检测到直接左递归文法,系统已停止运行,请改正产生式。endl;getchar();exit(0);/产生SELECT表Vt+=#;MAXITERATE=RULL.size()*RULL.size();vector SELECT;SELECT=Select();cout-SELECT集-endlSELECTendl;/检查for(i=0;iSELECT.size();i+)/

19、检查coutSELECTiendl;/检查SelectTable=new int*Vn.size();int* intp;for(i=0;iVn.size();i+)intp=new intVt.size();SelectTablei=intp;for(i=0;iVn.size();i+)for(j=0;jVt.size();j+) SelectTableij=-1;for(k=0;kSELECT.size();k+)for(l=2;lSELECTk.length();l+)i=inVn(SELECTk0);j=inVt(SELECTkl);SelectTableij=k;cout-Selec

20、tTable-endl ;/检测for(i=0;iVt.size();i+) coutVti ;/检测coutendl;/检测for(i=0;iVn.size();i+)/检测coutVni ;/检测for(j=0;jVt.size();j+) coutSelectTableij ;/检测coutendl;/检测/进行选择集相交检测if(check()=0)system(cls);system(color CF);cout选择集相交,该文法不是LL1文法,请修改产生式endl;getchar();exit(0);vector Select()int i;vector SELECT;string

21、 ps=;for(i=0;iRULL.size();i+)ps=RULLi0;ps+= ;ps+=first(RULLi);SELECT.push_back(ps);/迭代器清零counter=0;return SELECT;string first(string rull)/cout迭代次数counterMAXITERATE)system(cls);system(color CF);cout生成选择集时迭代次数过高,疑似出现递归死循环,系统已停止运行,请检查是否有语法错误endl;cout迭代次数上限暂设为产生式数量的平方。过多的迭代会损害设备,若没有语法错误,请简化语法树=0) res=r

22、ull3;else if(inVn(rull3)=0) for(i=0;i;for(j=3;jRULLi.size();j+) pp+=RULLij;for(j=4;jrull.size();j+) pp+=rullj;res+=first(pp);else if(rull3=0) res+=follow(rull);elsesystem(cls);system(color CF);cout产生式关键位置检测到非法字符,系统已停止运行。endl;getchar();exit(0);return res;string follow(string rull)/cout迭代次数counterMAXI

23、TERATE)system(cls);system(color CF);cout生成选择集时迭代次数过高,疑似出现递归死循环,系统已终止运行,请检查是否有语法错误endl;cout迭代次数上限暂设为产生式数量的平方。过多的迭代会损害设备,若没有语法错误,请简化语法树endl;getchar();exit(0);vector p;string res;string pp=;string t=;int i,site,j;if(rull0=Vs) res+=#;for(i=0;iRULL.size();i+)pp=;for(j=3;jRULLi.length();j+) pp+=RULLij;pp+

24、=0;site=pp.find(rull0,0);while(site;for(j=site+1;jpp.length();j+) t+=ppj;pp=t;if(pp3=0&pp0=rull0) continue;p.push_back(pp);site+;for(i=0;iZ , 入出口约定: 子程序入口时,其首符号已经读来!子程序出口时,其后继符应该读来! 子程序内容设计:遇终结符,判定之 ,确认后读下一单词;遇非终结符,调用之,返回后不读下一单词; 遇空串(e) ,直接出口; 入口出口NEXT(w)F 2Fyn入口出口NEXT(w)T 1Tynl 程序流程图如下:开始结束 #ENEXT(

25、w)err0yn 3.3中间语言生成器算法 中间语言生成主要是对四元式序列的设计,其算法设计如下: 1)赋值语句的四元式设计 设有赋值语句:v = E ,则有v = E =quat(E),q(:= res(E) _ v ) 算法实现如下: void Z(int end) /赋值语句四元式生成int i;string str;if(VTOKENtokenp+3.compare()!=0)tokenp+=2; LL1(end-1);str=VTOKENtokenp+1;str+=SEM.top();SEM.pop();str+=;str+=VTOKENtokenp;QT.push_back(str

26、);elsestr=VTOKENtokenp+1;str+=VTOKENtokenp+2;str+=;str+=VTOKENtokenp;QT.push_back(str);cout验证赋值语句并产生四元式 if(E)S1 else S2 quat(E)q1(if res(E)_ _ )quat(S1)q2(el _ _ _ )quat(S2)q3(ie _ _ _ )语义结构 : 四元式结构: E执行S1执行S2可选 falsetrue入口出口算法实现如下:void V(int end) /if语句四元式生成string str;int p,f=0;tokenp+;if(VTOKENtoke

27、pare()=0) f+=1;p=tokenp+1;else cout源代码错误-ERRO:02/if 当前TOKEN:tokenpendl; getchar();exit(0); do if(VTOKENpare()=0)f+=1; else if(VTOKENpare()=0)f-=1; p+; while(f!=0); if(p-1-tokenp)=1) cout源代码错误-ERRO:02/if括号 当前TOKEN:tokenpendl; getchar();exit(0); if(p-1-tokenp)=2) string tt; tt=VTOKENto

28、kenp+1; str=; str+=tt; str+=; str+=;QT.push_back(str);tokenp+=3; else tokenp+; LL1(p-2); tokenp=p; str=; str+=SEM.top(); SEM.pop(); str+=; str+=; QT.push_back(str); C(end);cout验证if语句并产生四元式endl;void N(int end) /else语句四元式生成 string str;str=;str+=;str+=;str+=;QT.push_back(str);tokenp+;C(end);cout验证else语

29、句并产生四元式 while(E)S 语义结构: 四元式结构:q2(do res(E)_ _ )quat(S)q3(we _ _ _ )q1(wh _ _ _ )quat(E) E 执行 Sfalsetrue入口 出口 算法实现如下:void W(int end) /循环语句四元式生成string str; int p,f=0;str=;str+=;str+=;str+=;QT.push_back(str);tokenp+;p=tokenp;do if(VTOKENpare()=0)f+=1; else if(VTOKENpare()=0)f-=1; p+; while(f!

30、=0); if(p-1-tokenp)=1) cout源代码错误-ERRO:02/while括号当前TOKEN:tokenpendl; getchar();exit(0); if(p-1-tokenp)=2) string tt; tt=VTOKENtokenp+1; str=; str+=tt; str+=; str+=;QT.push_back(str);tokenp+=3; elsetokenp+;LL1(p-2);str=;str+=SEM.top();SEM.pop();str+=;str+=;QT.push_back(str); tokenp=p;C(end);str=;str+=

31、;str+=;str+=;QT.push_back(str);cout验证了循环语句并产生四元式TX X-jTGX|0 T-FY Y-cFGY|0 F-MN N-bMGN|0 M-SQ Q-pSGQ|0 S-AB B-kAGB|0 A-iP|(E);四元式结构:q:( o1 o2 t )/*算符,对象1,对象2,结果*/算法实现如下:void GEQ(string a)/运算符a,计数器qtpchar p10;ele num;=t;num.val=0;int i=0;string str;string left;/左操作数string right;/右操作数string t;i

32、f(pare()=0|pare()=0)SEM.push(); right=SEM.top();SEM.pop();left=SEM.top();SEM.pop();if(left1=C)str=translate(left);for(i=0;isizeof(str);i+)if(stri=.)ITf.push_back(num);t+=;break;else continue;ITi.push_back(num);t+=;elseint flag=0;str=translate(left);for(i=0;iITi.size();i+)if(pare(IT)=0)flag=1;

33、break;else continue;for(i=0;iITf.size()&flag=0;i+)if(pare(IT)=0)flag=2;break;else continue;for(i=0;iITc.size()&flag=0;i+)if(pare(IT)=0)flag=3;break;else continue;switch(flag)case 0:cout使用了未声明的变量-ERRO:02 当前TOKEN:tokenpendl;exit(0);/未声明的变量case 1:ITi.push_back(num);t+=;break;case 2:ITf.pu

34、sh_back(num);t+=;break;case 3:ITc.push_back(num);t+=;break;if(right1=I&right3=,)int flag=0;str=translate(right);for(i=0;iITi.size();i+)if(pare(IT)=0)flag=1;break;else continue;for(i=0;iITf.size()&flag=0;i+)if(pare(IT)=0)flag=2;break;else continue;for(i=0;iITc.size()&flag=0;i+)if(pare(IT)=0)flag=3;break;else continue;if(flag=0)cout使用了未声明的变量-ERRO:02 当前TOKEN:tokenpendl;exit(0);a+=left;a+=right;a+=t;QT.push_back(a);SEM.push(t);2) 带语义动作的LL(1)自动机开始 初始化 #入栈,开始符号E入栈 N N/P? P read(w)执行栈操作(SYN(top),w)查分析表结束空?OK?

温馨提示

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

评论

0/150

提交评论