编译原理课程设计C语言编译器的实现_第1页
编译原理课程设计C语言编译器的实现_第2页
编译原理课程设计C语言编译器的实现_第3页
编译原理课程设计C语言编译器的实现_第4页
编译原理课程设计C语言编译器的实现_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

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

文档简介

1、精选优质文档-倾情为你奉上南华大学编译原理课程设计名:编译代生成器设计 专业 计算机科学与技术 学生姓名 熊浩斌 班 级 计算机01班 学 号 指导老师 陈星 实验地点 8栋 2-209 完成日期:2013.6.2一、课程设计的目的 编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,它在系统软件中占有十分重要的地位,是计算机专业学生的一门主修课。为了让学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识,提高他们的软件设计能力,特设定该课程的课程设计,通过设计一个简单的PASCAL语言(EL语言)的编译程序,提高学生设

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

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

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

5、um1用来存放整型单词;syn1用来存放单词符号的类型码。 有关scaner1()中关键点解析: while(ch=' ')|(ch='n') ch=progp+; ;忽略空格 if(ch<='z')&&(ch>='a')|(ch<='Z')&&(ch>='A') while(ch<='z')&&(ch>='a')|(ch<='Z')&&(ch&g

6、t;='A')|(ch>='0')&&(ch<='9') tokenm+=ch; ch=progp+; ;判别标识符 for(n=0;n<6;n+) if(strcmp(token,rwtabn)=0) syn=n+1; break; ;标识符是否是关键字 if(ch>='0')&&(ch<='9') while(ch>='0')&&(ch<='9') sum=sum*10+ch-'0&

7、#39; ch=progp+; ;判别整数 (3) 词法分析的运行结果 输入begin x:=1; y:=1+2;end # 输出4.3语法分析程序 (1) 具体功能的具体设计 1.yufafenxi()-分析程序 给出算术表达式文法,进行适当的文法变换输入表达式;输出表达式语法是否正确。 2.子程序的功能描述 (3) 语法分析的运行结果 分析成功图 分析失败图 4.4 中间代码生成程序(1)总体描述采用递归下降(自上而下)的语法制导翻译法。在前两次试验的基础上改进。词法分析程序 à 语法分析程序 à 语义分析程序 à编译器。不断完善,不断改进。渐变的过程。单词符

8、号及种别表单词符号种别编码单词值main1int 2float3double4char5if 6else 7do8while9l(l|d)*10内部字符串 ( +|-| ) d*(.dd* | )( e ( +|-| ) dd*|) 20二进制数值表示=21+22- 23* 24/ 25(26)272829,30;31>32>=33<34<=35=36!=37 (2)程序结构描述 (3) 程序的功能描述从文件中读入表达式,输出其四元式的结果序列 是否为main?调用scanner是否为(?调用scanner是否为)?调用scanner调用语句块分析函数staBlock出

9、错处理 递归下降示意图 (4)详细功能描述void scanner(); /扫描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();

10、/自动生成临时变量void backpatch(int p,int t); /回填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,

11、P2为链首的两条链合并成一条链,返回时的函数值作为合并后的链首。void backpatch(int p,int t)该函数的功能是把P所链接的每个四元式的第四区段(result段)都回 填t。void fuzhi()该函数的功能是对赋值语句进行分析。void tiaojian(int *nChain)该函数的功能是对条件语句进行分析。void xunhuan()该函数的功能是对循环语句进行分析。(4) 结果演示 图一 简单语句生成四元式 图二 if语句的四元式生成 图三 循环语句四元式生成(5)汇编生成if(strcmp(fourComi.opera,"=")=0) pr

12、intf("Move AX,%1sn",fourComi.arg1); printf("Move %5s,Axn",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.op

13、era,"-")=0) printf("Mov AX,%1sn",fourComi.arg1); printf("SUB Ax,%1sn",fourComi.arg2); printf("Mov %1s,Axn",fourComi.result);if(strcmp(fourComi.opera,"*")=0) printf("Mov AL,%1sn",fourComi.arg1); printf("MUL %1sn",fourComi.arg2); pr

14、intf("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("jmp L%1sn&quo

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

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

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

18、#include<math.h>#include<stdlib.h>#include<fstream>#include<iostream>using namespace std;#define MAX 100char inputstream50; /存储输入句子int temp1=0; /数组下标int right1; /判断输出信息int m2=0,sum2=0;/sum用于计算运算符的个数 /m用于标记输入表达式中字符的个数 char JG='A'char strMAX;/用于存输入表达式int tokene=0;/左括号的标

19、志char prog180,token18,ch1;int syn1,p1,m1,n1,sum1;char *rwtab16="begin","if","then","while","do","end"int r1 ;char prog80; /存放所有输入字符 char token8; /存放词组 char ch; /单个字符 int syn,p,m,n,i; /syn:种别编码 double sum; int count; int isSignal; /是否带正负号(0不

20、带,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 ntc,nfc,nnc,nnb,nna;char *rwtab9="main","int","float","double",&

21、quot;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

22、*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); /回填int merge(int p1,int p2); /合并p1和p2

23、void 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("缺少mai

24、nn");/<语句块> := ''<语句串>''void staBlock(int *nChain) /语句块if(syn=28) /scanner();staString(nChain);/backpatch(*nChain,nextq);if(syn=29) /scanner(); /读下一个elseprintf("缺少号n");elseprintf("缺少号n");/<语句串>:=<语句><语句>void staString(int *nChain

25、) /语句串sta(nChain);backpatch(*nChain,nextq);while(syn=31) /;scanner();sta(nChain);/backpatch(*nChain,nextq-1);void sta(int *nChain) /语句if(syn=10)fuzhi();/*nChain=0;else if(syn=6) /iftiaojian(nChain);else if(syn=8) /doxunhuan();/<条件语句>->if(<条件>)<语句块>void tiaojian(int *nChain)char

26、res10,num110,num210,op10;int nChainTemp;/<条件>-><表达式><关系运算符><表达式>if(syn=6) /ifscanner();/strcpy(num1,E();if(syn=26) /(scanner();strcpy(num1,E();if(syn<=37)&&(syn>=32) switch(syn)case 32:strcpy(op,">");break;case 33:strcpy(op,">=");bre

27、ak;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(&

28、quot;0","if",num1,"goto"); nfc=nextq; /if中表达式为假emit("0","","","goto");/第一个0已回填backpatch(ntc,nextq); /ntc链接的所有四元式都回填nextqif(syn=27) /)scanner();staBlock(&nChainTemp); /语句块*nChain=merge(nChainTemp,nfc);/<循环语句>:=do <语句块>wh

29、ile <条件>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); /语句块if(syn=9) /whilescanner();if(syn=26) /(scanner();strcpy(num1,E();if(syn<=37)

30、&&(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(&q

31、uot;error");scanner();strcpy(num2,E();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() /赋值语句只

32、有1个操作数char res10,num10; /num操作数if(syn=10) /字符串strcpy(res,token); /结果scanner();if(syn=21) /=scanner();strcpy(num,E();emit(res,num,"=","");elseprintf("缺少=号n");char* E() /Expression表达式char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op=(char *)mallo

33、c(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();emit(res,num1,op,num2);strcpy(num1,res);return num1;char* T() /Term项char *res,*num1,*op,*num2;res=(char *)malloc(

34、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();strcpy(res,newTemp();emit(res,num1,op,num2);strcpy(num1,res);return num1;char* F() /Factor因子

35、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=1;elseisError=1;return res;char *newTemp()char *p;char varTemp10;p=(char *)malloc(10);kk+;

36、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(fourComcircle.result,t); /把t填进四元式circle的第四分量sprintf(fourComcircle.result,"%d",t);

37、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.result,p1);sprintf(fourComcircle.result,"%s",p1);/目的是用p1的值

38、覆盖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; decimal=0; m=0; for(n=0;n<8;n+) tokenn=NULL; ch=progp+;

39、/从prog中读出一个字符到ch中 while(ch=' '|ch='n') /跳过空字符(无效输入) ch=progp+; if(ch>='a')&&(ch<='z')|(ch>='A')&&(ch<='Z') /ch是字母字符 while(ch>='a')&&(ch<='z')|(ch>='A')&&(ch<='Z')|(

40、ch>='0')&&(ch<='9') tokenm+=ch; /ch=>token ch=progp+; /读下一个字符 tokenm+='0' p-; /回退一格 syn=10; /标识符 /如果是"begin","if","then","while","do","end"标识符中的一个 for(n=0;n<9;n+) if(strcmp(token,rwtabn)=0) syn=n+

41、1; break; else if(ch>='0')&&(ch<='9') IsNum: if(isSignal=1) /tokenm+='-' while(ch>='0')&&(ch<='9') sum=sum*10+ch-'0' /ch中数字本身是当做字符存放的 ch=progp+; if(ch='.') isDecimal=1; ch=progp+; count=0; /之前忘了清零,123.123+123.123#两个浮

42、点数就无法识别 while(ch>='0')&&(ch<='9') /pow(x,y)计算x的y次幂 temp=(ch-'0')*pow(0.1,+count); decimal=decimal+temp; /AddToDec(); ch=progp+; sum=sum+decimal; if(ch='e'|ch='E') isExp=1; ch=progp+; if(ch='-') isNegative=1; ch=progp+; while(ch>='0

43、')&&(ch<='9') /指数 index=index*10+ch-'0' ch=progp+; /10的幂 /123e3代表123*10(3) /sum=sum*pow(10,index);是错误的 if(isNegative) sum=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

44、; ch=progp+; if(ch='=') syn=35; tokenm+=ch; else syn=34; p-; break; 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 '+':temp2=progp;tokenm+=ch;if(temp2>='0')&&(temp2<='9')&&(repeat=1)isSignal=2;ch=progp+;repeat=0;goto IsNum;if(temp2='+')|(temp2='-')&&(repeat=0) /如果重复出现符号,才将后边的+,-视为正负号repeat=1;/ch=progp+;syn=22;break;

温馨提示

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

评论

0/150

提交评论