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

下载本文档

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

文档简介

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

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

3、对简单程序设计语言中 的逻辑运算表达式、算术运算表达式、赋值语句、IF语句、While语句以及dowhile语句 进行编译,并生成中间代码和直接生汇编指令的代码生成器。 四、总体设计方案及详细设计 总体设计方案: 1. 总体模块 2. 表2.1各种单词符号对应的种别码 单词符号 种别码 单词符号 种别码 bgin 1 : 17 If 2 18 The n 3 20 wile 4 21 do 5 23 lettet (letter|digit)* 10 = 24 dight dight* 11 = 25 + 13 ; 26 一 14 ( 27 * 15 ) 28 / 16 # 0 详细设计: 4

4、.1界面导入设计 (1) 一共三个选项: choice 1cifafe nxi choice 2yufafenxi choice 3zhon gjia ndaima (2) 界面演示 图一 图三 C: IDOCUIE *11 eno?oi桌百 t 已 st t ry. ex e chnire 1ifdfenxi choire 1vufenxi choice 3zhongjundaifui If wwWWtfWfrWfl H wttT1 H WWtf FWWIf frWWW R 齐F WWW“ TlrWWtTWTTW *Tff 1TWF丹WWW ! frWWWFit BWW lie lea ne

5、! ?! (cifafenxi) please input a strlnifCenid uith 1 tJ )i/n hi II ! 1,1 la ii mi .i ii, ii ui mi u i,11 in u ii u u in 11 i i【i ii u in u, bi i.i n la ii iim ! ! ii ii ti m ib ii hi ! m tm# U Htlt# Rtttflfl 北 m# -BHUfl wUtlt# tlmfl ?#ni choice 1iffenxi choke 2jufftfonxi choke 3kngjiAndaina l/e Leone

6、! f(cifAfenxi) please input a Eti*Lnj(eni uith Jf ):Ail Ifels 時卄!(ynf 才馴gi please input a string ei( uith); 4.2词法分析程序 (2) 具体功能的具体设计 1、 cifafenxi( ) 首先设置 progn 来接收输入的语句,以 #来结束; 调用扫描子程序 scaner1( ),每一次得到一个类型码; 用 switch 判别相应输出; 直到 syn1=0 为止。 2、扫描子程序 scaner1( ) 扫描输入的语句 首先设置 3个变量 : token1 用来存放构成单词符号的字符串;

7、suml用来存放整型单词; syn1 用来存放单词符号的类型码。 有关 scaner1() 中关键点解析: while(ch= )|(ch=n) ch=progp+; ;忽略空格 if(ch=a)|(ch=A) while(ch=a)|(ch=A)|(ch=0) ch=progp+; ;判别标识符 for(n=0;n=0) printf(Move %5s,Axn,fourComi.result); if(strcmp(fourComi.opera,+)=0) prin tf(Mov AX,%1sn,fourComi.arg1); prin tf(ADD Ax,%1sn,fourComi.arg

8、2); prin tf(Mov %1s,Axn,fourComi.result); if(strcmp(fourComi.opera,- )=0) prin tf(Mov AX,%1sn,fourComi.arg1); prin tf(SUB Ax,%1sn,fourComi.arg2); prin tf(Mov %1s,Axn,fourComi.result); if(strcmp(fourComi.opera,*)=0) prin tf(Mov AL,%1sn,fourComi.arg1); prin tf(MUL %1sn,fourComi.arg2); prin tf(Mov %1s,

9、Axn,fourComi.result); if(strcmp(fourComi.opera,/)=0) prin tf(Mov AX,%1sn,fourComi.arg1); printf(Dlv %1sn,fourComi.arg2); printf(Mov %1s,ALn,fourComi.result); if(strcmp(fourComi.opera,goto)=0) prin tf(jmp L%1sn ,i); 结果演示 五、课程设计的体会与总结 经过一个星期的编译原理课程设计,本人在陈宏建老师的指导下,顺利完成该课程 设 计。通过该课程设计,收获颇多。 词法分析的基本任务是从字

10、符串表示的源程序中识别出具有独立意义的单词符号,其 基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。通过本试验的 完成,更加加深了对词法分析原理的理解。 通过本次试验,了解了语法分析的运行过程,主程序大致流程为:“置初值” 调用 scaner函数读下一个单词符号 调用IrParse结束。递归下降分析的大致流程为:“先判断 是否为begin” 不是则“出错处理”,若是则“调用scaner函数” 调用语句串分析函数 “判断是否为end”不是则“出错处理”,若是则调用scaner函数 “判断syn=O #define MAX 100 char inputstream50; / 存

11、储输入句子 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; / 存放所有输入字符 char token8; / 存放词组 char

12、 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; / 临时变量的标号 in

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

14、id 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); /

15、 回填 int merge(int p1,int p2); / 合并 p1 和 p2 void emit(char *res,char *num1,char *op,char *num2); / 生成四元式 void scanner(); / 扫描 void lrparser() int nChain; nfc=ntc=1; nextq=1; if(syn=1) /main scanner(); if(syn=26) /( scanner(); if(syn=27) /) scanner(); staBlock( else printf( 缺少右括号 n); else printf( 缺少左括

16、号 n); else printf( 缺少 mainn); / := void staBlock(int *nChain) / 语句块 if(syn=28) / scanner(); staString(nChain); /backpatch(*nChain,nextq); if(syn=29) / scanner(); / 读下一个 else printf( 缺少 号 n); else printf(缺少号n”); /:= ; void staString(int *nChain) / 语句串 sta(nChain); backpatch(*nChain,nextq); while(syn=

17、31) /; scanner(); sta(nChain); /backpatch(*nChain,nextq-1); void sta(int *nChain) / 语句 if(syn=10) fuzhi(); /*nChain=0; else if(syn=6) /if tiaojian(nChain); else if(syn=8) /do xunhuan(); /-if() void tiaojian(int *nChain) char res10,num110,num210,op10; int nChainTemp; /- if(syn=6) /if scanner(); /strc

18、py(num1,E(); 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(n

19、um2,E(); strcat(num1,op); strcat(num1,num2); /nfc=nextq+1; ntc=nextq; / 记住 if 语句位置 emit(0,if,num1,goto); nfc=nextq; /if 中表达式为假 emit(0,goto); nextq /第一个 0 已回填 backpatch(ntc,nextq); /ntc 链接的所有四元式都回填 if(syn=27) /) scanner(); staBlock( / 语句块 *nChain=merge(nChainTemp,nfc); /:=do while void xunhuan() char

20、 res10,num110,num210,op10; int nChainTemp; if(syn=8) /do nnc=nextq; /记住 if 语句位置, emit 之后 nextq 就变了 /emit(0,if,num1,goto); scanner(); staBlock( / 语句块 if(syn=9) /while scanner(); if(syn=26) /( scanner(); strcpy(num1,E(); if(syn=32) switch(syn) case 32: strcpy(op,); break; case 33: strcpy(op,=); break;

21、 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); nnb=nextq; emit(0,if,num1,goto); backpatch(nnb,nnc); nna=nextq; emit(0,goto); backpatch(nna

22、,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,num,=,); else printf( 缺少 =号 n); char* E() /Expression 表达式 char *res,*num1,*op,*num2; res=(char *)malloc(10);

23、 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,+); else strcpy(op,-); scanner(); strcpy(num2,T(); strcpy(res,newTemp(); emit(res,num1,op,num2); strcpy(num1,res); return num1; char* T() /Term 项 char *res,*

24、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,*); else strcpy(op,/); scanner(); strcpy(num2,F(); strcpy(res,newTemp(); emit(res,num1,op,num2); strcpy(num1,res); return

25、 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=1; else isError=1; return res; char *newTemp()

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

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

28、le.result,p1); sprintf(fourComcircle.result,%s,p1); /目的是用 p1 的值覆盖 0 return 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+; voi

29、d scanner() sum=0; decimal=0; m=0; for(n=0;n=a) / 读下一个字符 tokenm+=0; p-; / 回退一格 syn=10; / 标识符 标识符中的一个 /如果是 begin,if,then,while,do,end for(n=0;n=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=-

30、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 +: temp2=progp; tokenm+=ch; if(temp2=0) ch=progp+; / 读 - 下一个字符 repeat=0; go

31、to IsNum; / 转到数字的识别 /如果重复出现符号,才将后边 if(temp2=+)|(temp2=-) / 预言会重复 /ch=progp+; / 读下一个字符 syn=23; break; 1*1. 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=+) i

32、sSignal=2; repeat=1; else if(temp2=-) isSignal=1; repeat=1; syn=26; break; case ): syn=27; tokenm+=ch; break; case : syn=28; tokenm+=ch; break; case : syn=29; tokenm+=ch; break; case ,: syn=30; tokenm+=ch; break; case ;: syn=31; tokenm+=ch; break; case#: syn=0; tokenm+=ch; break; default: syn=-1; zh

33、ongjiandaima() p=0; count=0; isDecimal=0; index=0; repeat=0; kk=0; printf(nPlease input your source string:n); do ch=getchar(); progp+=ch; while(ch!=#); p=0; isError=0; scanner(); lrparser(); for(i=1;inextq;i+) / 循环输出四元式 printf(n%dt,i); printf(%3s, %3s ,%3s , %3s )n,fourComi.opera,fourComi.arg1,four

34、Comi.arg2,fou rComi.result); if(strcmp(fourComi.opera,=)=0) printf(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.opera,-)=

35、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); printf(Mov %1s,Axn,fourComi.result); if(strcmp(fourComi.opera,/)=0) printf(Mov AX,%1sn,fourC

36、omi.arg1); printf(DIv %1sn,fourComi.arg2); printf(Mov %1s,ALn,fourComi.result); if(strcmp(fourComi.arg2,goto)=0 printf(jnc %1sn,fourComi.result); else printf(jmp %1sn,fourComi.result); return; void main() printf( n); printf( n); printf( II II II II II II II II II II II II II II II II II II II II II

37、II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a n); printf( choice

38、 1cifafenxin); printf( choice 2yufafenxin); printf( choice 3zhongjiandaimann); printf( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a

39、 a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a n); scanf(%d, do switch(r1) case 1: cifafenxi(); scanf(%d, break; case 2:yufafenxi() ; scanf(%d, break; case 3:zhongjiandaima(); scanf(%d, break; default: printf(error,please input again); break; p1=0; printf( printf(n do Welcome!(cifafe

40、nxi) please input a string(end with #):/n); cifafenxi() while(r1!=0); scanf(%c, prog1p1+=ch1; while(ch1!=#); p1=0; do scaner1(); switch(syn1) case 11:printf( %-10d%5d )n,sum1,syn1); break; case -1:printf(you have input a wrong stringn); exit(0); default: printf( %-10s%5d )n,token1,syn1); break; whil

41、e(syn1!=0); scaner1() sum1=0; for(m1=0;m18;m1+)token1m1+=NULL; ch1=prog1p1+; m1=0; while(ch1= )|(ch1=n)ch1=prog1p1+; if(ch1=a)|(ch1=A) while(ch1=a)|(ch1=A)|(ch1=0) ch1=prog1p1+; p1-; syn1=10; for(n1=0;n1=0) ch1=prog1p1+; p1-; syn1=11; else switch(ch1) case :token1m1+=ch1; ch1=prog1p1+; if(ch1=) syn1=24; token1m1+=ch1; else syn1=23; p1-; break; case +: token1m1+=ch1; ch1=prog1p1+; if(ch1=+) syn1=17; to

温馨提示

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

评论

0/150

提交评论