编译原理课程设计 编译代码生成器设计_第1页
编译原理课程设计 编译代码生成器设计_第2页
编译原理课程设计 编译代码生成器设计_第3页
编译原理课程设计 编译代码生成器设计_第4页
编译原理课程设计 编译代码生成器设计_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

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

文档简介

1、编译原理课程设计报告题目 编译代码生成器设计学院信息科学与工程学院专业计算机科学与技术班级 * 学号 * 学生姓名*指导教师 * 课程成绩完成日期 * 课程设计成绩评定学院信息学院专业计算机科学与技术班级* 学号*学生姓名*指导教师 * 课程成绩完成日期 * 指导教师对学生在课程设计中的评价评分项目优良中及格不及格课程设计中的创造性成果学生掌握课程内容的程度课程设计完成情况课程设计动手能力文字表达学习态度规范要求课程设计论文的质量指导教师对课程设计的评定意见综合成绩 指导教师签字 *年 月 题目编译代码生成器设计学生姓名:*指导老师:*摘要使用过现代计算机的人都知道,多数用户是应用高级语言来实

2、现他们所需要的计算的。现在计算机系统一般都含有不只一个的高级语言的编译程序,对有些高级语言甚至配置了几个不同性能的编译程序,供用户按不同需要进行选择。高级语言编译程序是计算机系统软件最主要的组成部分之,也是用户最直接关系的工具之一。计算机上执行一个高级语言程序一般分为两步:第一,用一个编译程序把高级语言翻译成机器语言程序;第二,运行所得的机器语言程序求得计算结果。通常说的翻译程序是指能够把某一种语言程序转换成另一种语言程序(目标语言程序)。如果源语言诸如Fortran,Pascal,C,Ada或java这样的高级语言,而目标程序是诸如汇编语言或者机器语言这类的低级语言,这样的一个翻译程序就是称

3、为编译程序。一个编译程序的工作过程一般可以划分为五个阶段:词法分析、语法分析、语义分析与中间代码生成、优化、目标代码生成。每个阶段都是从上一个阶段得到结果,对他进行分析,并且根据一些外部环境(例如符号表等)得到最终的输出结果。要构造一个编译程序,可以按照这样的阶段来分别构造,最后来连调。现在人们已经建立了多种编制部分编译程序或整个编译程序的有效工具。有些能用于自动生成扫描器(如LEX),有些可以用于自动产生语法分析器(如YACC),有些甚至可以用来自动产生整个的编译程序。这些构造编译程序的工具成为编译程序编译程序、编译程序产生器或翻译程序书写系统,他们是按照编译程序和目标语言的形式描述而自动产

4、生编译程序的。编译程序是一极其庞大而又复杂的系统,掌握它比较苦难。但是一旦对其掌握,对以后的程序语言设计,系统软件分析,系统软件设计,形式语言研究等方面都是非常有好处的。关键字:C语言、编译、扫描器、语法分析一、课程设计的目的编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,它在系统软件中占有十分重要的地位,是计算机专业学生的一门主修课。为了让学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识,提高他们的软件设计能力,特设定该课程的课程设计,通过设计一个简单的PASCAL语言(EL语言)的编译程序,提高学生设计程序的

5、能力,加深对编译理论知识的理解与应用。二、课程设计的要求1、 明确课程设计任务,复习编译理论知识,查阅复印相关的编译资料。2、 按要求完成课程设计内容,课程设计报告要求文字和图表工整、思路清晰、算法正确。3、 写出完整的算法框架。4、 编写完整的编译程序。 三、课程设计的内容课程设计是一项综合性实践环节,是对平时实验的一个补充,课程设计内容包括课程的主要理论知识,但由于编译的知识量较复杂而且综合性较强,因而对一个完整的编译程序不适合平时实验。通过课程设计可以达到综合设计编译程序的目的。本课程的课程设计要求学生编写一个完整的编译程序,包括词法分析器、语法分析器以及实现对简单程序设计语言中的逻辑运

6、算表达式、算术运算表达式、赋值语句、IF语句、While语句以及dowhile语句进行编译,并生成中间代码和直接生汇编指令的代码生成器。四、总体设计方案及详细设计主程序词法分析程序语法分析程序中间代码生成程序总体设计方案:1.总体模块2.表2.1 各种单词符号对应的种别码单词符号种别码 单词符号种别码bgin1:17If2:=18Then320wile421do523lettet(letter|digit)*10=24dight dight*11=25+13;2614(27*15)28/16#0详细设计: 4.1界面导入设计(1)一共三个选项:choice 1-cifafenxichoice

7、2-yufafenxichoice 3-zhongjiandaima (2)界面演示 图一 图二 图三4.2词法分析程序置初值调用扫描子程序输出单词二元组输入串结束结束否是(1)流程图设计(2)具体功能的具体设计1、cifafenxi( ) 首先设置progn来接收输入的语句,以#来结束; 调用扫描子程序 scaner1( ),每一次得到一个类型码; 用switch判别相应输出; 直到syn1=0为止。2、扫描子程序scaner1( )-扫描输入的语句首先设置3个变量:token1用来存放构成单词符号的字符串;sum1用来存放整型单词;syn1用来存放单词符号的类型码。有关scaner1()中

8、关键点解析:while(ch= )|(ch=n)ch=progp+; ;忽略空格if(ch=a)|(ch=A) while(ch=a)|(ch=A)|(ch=0)&(ch=9)tokenm+=ch; ch=progp+;;判别标识符for(n=0;n=0)&(ch=0)&(ch32=3334=35=36!=37(2)程序结构描述(3) 程序的功能描述从文件中读入表达式,输出其四元式的结果序列 是否为main?调用scanner是否为(?调用scanner是否为)?调用scanner调用语句块分析函数staBlock出错处理 递归下降示意图 (4)详细功能描述void scanner(); /扫

9、描void lrparser(); void staBlock(int *nChain); /语句块void staString(int *nChain); /语句串void sta(int *nChain); /语句void fuzhi(); /赋值语句void tiaojian(int *nChain); /条件语句void xunhuan(); /循环语句char* E(); /Expresiion表达式char* T(); /Term项char* F(); /Factor因子char *newTemp(); /自动生成临时变量void backpatch(int p,int t); /

10、回填int merge(int p1,int p2); /合并p1和p2void emit(char *res,char *num1,char *op,char *num2); /生成四元式void emit(char *res,char *num1,char *op,char *num2) 该函数的功能是生成一个三地址语句送到四式表中 char *newTemp()该函数的功能是会动一个新的临时变量,临时变量名产生的 顺序是T1,T2,T3,.int merge(int p1,int p2)该函数的功能是将以P1,P2为链首的两条链合并成一条链,返回时的函数值作为合并后的链首。void ba

11、ckpatch(int p,int t)该函数的功能是把P所链接的每个四元式的第四区段(result段)都回 填t。void fuzhi()该函数的功能是对赋值语句进行分析。void tiaojian(int *nChain)该函数的功能是对条件语句进行分析。void xunhuan()该函数的功能是对循环语句进行分析。(4) 结果演示 图一 简单语句生成四元式 图二if语句的四元式生成图三循环语句四元式生成(5)汇编生成if(strcmp(fourComi.opera,=)=0) printf(Move AX,%1sn,fourComi.arg1); printf(Move %5s,Axn,

12、fourComi.result);if(strcmp(fourComi.opera,+)=0) printf(Mov AX,%1sn,fourComi.arg1); printf(ADD Ax,%1sn,fourComi.arg2);printf(Mov %1s,Axn,fourComi.result);if(strcmp(fourComi.opera,-)=0) printf(Mov AX,%1sn,fourComi.arg1); printf(SUB Ax,%1sn,fourComi.arg2); printf(Mov %1s,Axn,fourComi.result);if(strcmp(

13、fourComi.opera,*)=0) printf(Mov AL,%1sn,fourComi.arg1); printf(MUL %1sn,fourComi.arg2); printf(Mov %1s,Axn,fourComi.result);if(strcmp(fourComi.opera,/)=0) printf(Mov AX,%1sn,fourComi.arg1); printf(DIv %1sn,fourComi.arg2); printf(Mov %1s,ALn,fourComi.result);if(strcmp(fourComi.opera,goto)=0) printf(j

14、mp L%1sn,i);结果演示五、课程设计的体会与总结 经过一个星期的编译原理课程设计,本人在陈宏建老师的指导下,顺利完成该课程设 计。通过该课程设计,收获颇多。 词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。通过本试验的完成,更加加深了对词法分析原理的理解。 通过本次试验,了解了语法分析的运行过程,主程序大致流程为:“置初值”调用scaner函数读下一个单词符号调用IrParse结束。递归下降分析的大致流程为:“先判断是否为begin”不是则“出错处理”,若是则“调用scaner函数”调用语句串

15、分析函数“判断是否为end”不是则“出错处理”,若是则调用scaner函数“判断syn=0&kk=0是否成立”成立则说明分析成功打印出来。不成立则“出错处理”。 一、对实验原理有更深的理解通过该课程设计,掌握了什么是编译程序,编译程序工作的基本过程及其各阶段的基本任务,熟悉了编译程序总流程框图,了解了编译程序的生成过程、构造工具及其相关的技术对课本上的知识有了更深的理解,课本上的知识师机械的,表面的。通过把该算法的内容,算法的执行顺序在计算机上实现,把原来以为很深奥的书本知识变的更为简单,对实验原理有更深的理解。二、对该理论在实践中的应用有深刻的理解通过把该算法的内容,算法的执行顺序在计算机上

16、实现,知道和理解了该理论在计算机中是怎样执行的,对该理论在实践中的应用有深刻的理解。三、激发了学习的积极性通过该课程设计,全面系统的理解了编译原理程序构造的一般原理和基本实现方法。把死板的课本知识变得生动有趣,激发了学习的积极性。把学过的计算机编译原理的知识强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了对理论知识的理解。以前对与计算机操在这次课程设计中,我就是按照实验指导的思想来完成。加深了理解文件系统的内部功能及内部实现,培养实践动手能力和程序开发能力的目的。附录-程序清单#include#include#include#includeusing namespace std;#

17、define MAX 100char inputstream50; /存储输入句子int temp1=0; /数组下标int right1; /判断输出信息int m2=0,sum2=0;/sum用于计算运算符的个数 /m用于标记输入表达式中字符的个数char JG=A;char strMAX;/用于存输入表达式int tokene=0;/左括号的标志char prog180,token18,ch1;int syn1,p1,m1,n1,sum1;char *rwtab16=begin,if,then,while,do,end;int r1 ;char prog80; /存放所有输入字符 cha

18、r token8; /存放词组 char ch; /单个字符 int syn,p,m,n,i; /syn:种别编码 double sum; int count; int isSignal; /是否带正负号(0不带,1负号,2正号)int isError;int isDecimal; /是否是小数 double decimal; /小数 int isExp; /是否是指数 int index; /指数幂 int isNegative; /是否带负号 double temp; int temp2;int repeat; /是否连续出现+,-int nextq;int kk; /临时变量的标号int

19、 ntc,nfc,nnc,nnb,nna;char *rwtab9=main,int,float,double,char,if,else,do,while; structchar result10; /字符串(字符数组)char arg110;char opera10;char arg210;fourCom20; /结构体数组cifafenxi();yufafenxi();zhongjiandaima();scaner1();void e();void e1();void t();void t1();void f();void lrparser(); void staBlock(int *nC

20、hain); /语句块void staString(int *nChain); /语句串void sta(int *nChain); /语句void fuzhi(); /赋值语句void tiaojian(int *nChain); /条件语句void xunhuan(); /循环语句char* E(); /Expresiion表达式char* T(); /Term项char* F(); /Factor因子char *newTemp(); /自动生成临时变量void backpatch(int p,int t); /回填int merge(int p1,int p2); /合并p1和p2voi

21、d emit(char *res,char *num1,char *op,char *num2); /生成四元式void scanner(); /扫描void lrparser()int nChain;nfc=ntc=1;nextq=1;if(syn=1) /mainscanner();if(syn=26) /(scanner();if(syn=27) /)scanner();staBlock(&nChain);elseprintf(缺少右括号n);else printf(缺少左括号n);elseprintf(缺少mainn);/ := void staBlock(int *nChain) /

22、语句块if(syn=28) /scanner();staString(nChain);/backpatch(*nChain,nextq);if(syn=29) /scanner(); /读下一个elseprintf(缺少号n);elseprintf(缺少号n);/:=;void staString(int *nChain) /语句串sta(nChain);backpatch(*nChain,nextq);while(syn=31) /;scanner();sta(nChain);/backpatch(*nChain,nextq-1);void sta(int *nChain) /语句if(sy

23、n=10)fuzhi();/*nChain=0;else if(syn=6) /iftiaojian(nChain);else if(syn=8) /doxunhuan();/-if()void tiaojian(int *nChain)char res10,num110,num210,op10;int nChainTemp;/-if(syn=6) /ifscanner();/strcpy(num1,E();if(syn=26) /(scanner();strcpy(num1,E();if(syn=32) switch(syn)case 32:strcpy(op,);break;case 33

24、:strcpy(op,=);break;case 34:strcpy(op,);break;case 35:strcpy(op,=);break;case 36:strcpy(op,=);break;case 37:strcpy(op,!=);break;default:printf(error);scanner();strcpy(num2,E();strcat(num1,op);strcat(num1,num2);/nfc=nextq+1;ntc=nextq; /记住if语句位置emit(0,if,num1,goto); nfc=nextq; /if中表达式为假emit(0,goto);/第

25、一个0已回填backpatch(ntc,nextq); /ntc链接的所有四元式都回填nextqif(syn=27) /)scanner();staBlock(&nChainTemp); /语句块*nChain=merge(nChainTemp,nfc);/:=do while void xunhuan()char res10,num110,num210,op10;int nChainTemp;if(syn=8) /donnc=nextq; /记住if语句位置,emit之后nextq就变了/emit(0,if,num1,goto); scanner();staBlock(&nChainTemp

26、); /语句块if(syn=9) /whilescanner();if(syn=26) /(scanner();strcpy(num1,E();if(syn=32) switch(syn)case 32:strcpy(op,);break;case 33:strcpy(op,=);break;case 34:strcpy(op,);break;case 35:strcpy(op,=);break;case 36:strcpy(op,=);break;case 37:strcpy(op,!=);break;default:printf(error);scanner();strcpy(num2,E

27、();strcat(num1,op);strcat(num1,num2);nnb=nextq;emit(0,if,num1,goto); backpatch(nnb,nnc);nna=nextq;emit(0,goto);backpatch(nna,nextq);if(syn=27) /)scanner();void fuzhi() /赋值语句只有1个操作数char res10,num10; /num操作数if(syn=10) /字符串strcpy(res,token); /结果scanner();if(syn=21) /=scanner();strcpy(num,E();emit(res,n

28、um,=,);elseprintf(缺少=号n);char* E() /Expression表达式char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op=(char *)malloc(10);num2=(char *)malloc(10);strcpy(num1,T();while(syn=22)|(syn=23) /+ -if(syn=22) /+strcpy(op,+);elsestrcpy(op,-);scanner();strcpy(num2,T();strcpy(res,newTemp()

29、;emit(res,num1,op,num2);strcpy(num1,res);return num1;char* T() /Term项char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op=(char *)malloc(10);num2=(char *)malloc(10);strcpy(num1,F();while(syn=24)|(syn=25) /* /if(syn=24) strcpy(op,*);elsestrcpy(op,/);scanner();strcpy(num2,F();st

30、rcpy(res,newTemp();emit(res,num1,op,num2);strcpy(num1,res);return num1;char* F() /Factor因子char *res;res=(char *)malloc(10);if(syn=10) /字符串strcpy(res,token);scanner();else if(syn=20) /二进制数itoa(int)sum,res,10); /整数转换为字符串scanner();else if(syn=26) /(scanner();res=E();if(syn=27) /)scanner();else isError=

31、1;elseisError=1;return res;char *newTemp()char *p;char varTemp10;p=(char *)malloc(10);kk+;itoa(kk,varTemp,10);strcpy(p+1,varTemp);p0=T;return p;/将p所链接的每个四元式的第四个分量都回填tvoid backpatch(int p,int t) int w,circle=p;while(circle) /circle不为0的时候w=atoi(fourComcircle.result); /四元式circle第四分量内容/strcpy(fourComcir

32、cle.result,t); /把t填进四元式circle的第四分量sprintf(fourComcircle.result,%d,t);circle=w; /w记录的是链条上下一个四元式,移动!return;int merge(int p1,int p2) /合并p1和p2char circle,nResult;if(p2=0)nResult=p1;elsenResult=circle=p2;while(atoi(fourComcircle.result) /四元式第四个分量不为0circle=atoi(fourComcircle.result); /strcpy(fourComcircle

33、.result,p1);sprintf(fourComcircle.result,%s,p1);/目的是用p1的值覆盖0return nResult; /p2是头,p1覆盖0,接在p2后边void emit(char *res,char *num1,char *op,char *num2)strcpy(fourComnextq.result,res);strcpy(fourComnextq.arg1,num1);strcpy(fourComnextq.opera,op);strcpy(fourComnextq.arg2,num2);nextq+;void scanner() sum=0; de

34、cimal=0; m=0; for(n=0;n=a)&(ch=A)&(ch=a)&(ch=A)&(ch=0)&(chtoken ch=progp+; /读下一个字符 tokenm+=0; p-; /回退一格 syn=10; /标识符 /如果是begin,if,then,while,do,end标识符中的一个 for(n=0;n=0)&(ch=0)&(ch=0)&(ch=0)&(ch=9) /指数 index=index*10+ch-0; ch=progp+; /10的幂 /123e3代表123*10(3) /sum=sum*pow(10,index);是错误的 if(isNegative) s

35、um=sum*pow(0.1,index); else sum=sum*pow(10,index); if(isSignal=1)sum=-sum;isSignal=0; p-; syn=20; else switch(ch) case : m=0; tokenm+=ch; ch=progp+; if(ch=) syn=33; tokenm+=ch; else syn=32; p-; break; case =: m=0; tokenm+=ch; ch=progp+; if(ch=) syn=36; tokenm+=ch; else syn=21; p-; break; case +:temp

36、2=progp;tokenm+=ch;if(temp2=0)&(temp2=0)&(temp2=9)&(repeat=1)isSignal=1;ch=progp+; /读-下一个字符repeat=0;goto IsNum; /转到数字的识别if(temp2=+)|(temp2=-)&(repeat=0) /如果重复出现符号,才将后边的+,-视为正负号repeat=1; /预言会重复/ch=progp+; /读下一个字符syn=23;break; case *:temp2=progp;tokenm+=ch;if(temp2=+)isSignal=2;repeat=1;else if(temp2=-)isSignal=1;repeat=1;syn=24;break; case /: syn=25; tokenm+=ch; break; case (:temp2=progp;tokenm+=ch;if(temp2=+)isSignal=2;repeat=1;else if(temp2=-)isSignal=1;repeat=1;syn=26;break; case ): syn=27; tokenm+=ch; break; case : syn=28; token

温馨提示

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

评论

0/150

提交评论