编译器编译原理课程设计报告书.docx
- 文档编号:10429283
- 上传时间:2023-02-11
- 格式:DOCX
- 页数:68
- 大小:532.47KB
编译器编译原理课程设计报告书.docx
《编译器编译原理课程设计报告书.docx》由会员分享,可在线阅读,更多相关《编译器编译原理课程设计报告书.docx(68页珍藏版)》请在冰豆网上搜索。
编译器编译原理课程设计报告书编译器编译原理课程设计报告书广西大学编译原理课程设计专业:
计算机科学与技术姓名:
课程:
编译原理指导教师:
一程序简介与分析-1二程序适用范围-1三词法分析-1四语法分析-3五语义分析和中间代码生成-9六代码生成-11七流程图-12八实现-13九程序运行结果-13十总结-18十一.附录(源程序)-19简单的编译程序设计一程序简介与分析本程序由四个部分组成:
词法分析子程序,语法分析子程序,语义分析子程序,目标代码生成程序。
本程序输入一个叫haominjie.txt的c语言源程序,然后对它进行词法,语法,语义分析,并输出汇编代码。
词法分析输入的是c语言源程序,输出的3是具有独立语法意义的单词符号。
语法分析以词法分析产生的编码流为输入,按照SLR
(1)分析方法进行语法分析,产生语法树,输出移进和归约的动作,如果源程序不符合文法,则有“语法分析出错”的提示。
语义分析阶段,在语法分析的同时,在归约的时候,给出相应的语义动作,最后输出中间代码四元式和新的符号表,如果有未声明的变量出现,则会提示出出错,并显示出此变量的名称。
代码生成阶段,将语义分析得到的中间代码四元式转化为汇编语言的目标代码并输出。
二程序适用范围本程序的使用范围为:
整型常量,四则运算(为了简化问题,本程序只考虑加法运算和乘法运算)和布尔表达式以及相应的赋值语句,条件转移语句和循环语句。
三词法分析根据词法分析的需要,我将源程序中的单词符号分为:
保留字,字母(标识符),界符三类,统一用一张表表示如下:
界符,保留字表词ndfthenwhileont志符码0123335675程序从源程序文件haominjie.txt中一次读入一个字符,并判断它是不是字母,界符,保留字,空格,换行,结束符号或者非法字符。
流程图如下:
词法分析流程图四语法分析源程序中涉及的文法GP定义如下表:
说明语句表达式布尔表达式句法0、PP1、Pid()L;R2、LL;D3、LD4、Did:
int5、EE+T6、ET7、TT*F8、TF9、F(E)10、Fid11、BBandB12、Bidid13、Mid=E14、SifBthenM15、SwhileBdoM16、SM17、NN;S18、NS19、RN.上述文法的每个非终结符的FIRST集和FOLLOW集如下表:
FIRST集FOLLOW集Pid#Lid;Did;E(,id,;,+,),#T(,id,;,+,),*,#F(,id,;,+,),*,#Bidthen,do,andMid,;Sid,while,if,;Nid,while,if,;R#.文法GP的项目集部分如下:
0.P.P1.PP.2.P.id()L;R3.Pid.()L;R4.Pid(.)L;R5.Pid().L;R6.Pid()L.;R7.Pid()L;.R8.Pid()L;R.9.L.L;D10.LL.;D11.LL;.D12.LL;D.13.D.id:
int14.Did.:
int15.Did:
.int16.Did:
int.17.E.E+T18.EE.+T19.EE+.T20.EE+T.21.E.T22.ET.23.T.T*F24.TT.*F25.TT*.F26.TT*F.27.T.F28.TF.29.F(E)30.F(.E)31.F(E.)32.F(E).33.F.id34.Fid.再由项目集构造文法的DFA活前缀。
为了方便,省去了项目族集的每个状态的项目,直接在状态转换的箭头上标明终结符或非终结符。
对于有规约动作和接受的状态,将其特别标明。
文法GP的DFA图如下:
:
int说明语句DidDidR;L)(idPifBthenMidandid句法Sid=ifidMN;SidMwhilewhileBdoMidandidB布尔表达式andidTidid(FE*(F(idFid+E(表达式+)T*GP:
SLR
(1)分析表Actiongotodntndfhenhileo0123456702cc3456743100513211122314232721741553641687613431371918819914232720GP:
SLR
(1)分析表Actiongotodntndfhhioenle012345670017171181821616331443425514661414731883491429001515132233312121243155111111610101010107888888663966936410GP:
SLR
(1)分析表actiongotodntndfhenhileo012345670077777136412872454333641474553955599999五语义分析和中间代码生成载语法分析过程中,随着分析的步步进展,根据每个产生式所对应的语义子程序(或语义规则描述的语义动作)进行翻译的办法称作语法制导翻译。
语法制导翻译归约动作翻译方案EE+TEE1+TE.place=newtemp;Emit(E.place:
=E1.place+T.place);ETETE.place:
=T.place;TT*FTT1*FT.place=newtemp;Emit(T.place:
=T1.place+F.place);TFTFT.place:
=F.place;F(E)F(E)F.place:
=E.place;FidFidp:
=lookup(id.name);ifpnilthenF.place:
=pelseerror;BBandBBB1andAB2backpatch(B1.truelist,A.quad);B.truelist:
=B2.truelist;B.falselist:
=merge(B1.falselist,B2.falselist);AA.quad:
=nextquadBididBid1id2B.truelist:
=makelist(nextquad);B.falselist:
=makelist(nextquad+1);emit(ifid1.placeid2.placegoto__);emit(goto__);Mid=EMid=Ep:
=lookup(id.name);ifpnilthenemit(p:
=E.place)elseerror;SifBthenMSifBthenAMbackpatch(B.truelist,A.quad)backpatch(B.falselist,nextquad)AA.quad:
=nextquadSwhileBdoMSwhileA1BdoA2Mbackpatch(B.truelist,A2.quad)backpatch(B.falselist,nextquad+1)emit(gotoA1.quad)A1A1.quad:
=nextquadA2A2.quad:
=nextquad语法翻译生成的四元式如下:
六代码生成目标代码生成阶段的任务是把中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码。
这是编译的最后阶段,它的工作与硬件系统结构和指令含义有关,这个阶段的工作很复杂,涉及到硬件系统功能部件的运用、机器指令的选择、各种数据类型变量的存储空间分配以及寄存器和后缓寄存器的调度等。
本程序生成的目标代码与0x8086微处理器兼容。
下面列举几个简单的四元式与汇编代码的转化列子:
(+,A,B,T)MOVR,A;ADDR,B;STR,T.(*,A,B,T)MOVR,A;MULR,B;STR,T.(J,_,_,L)JMPL.(J,A,B,L)MOVR,ACMPR,BJBL.(=,A,_,T)LDR,ASTR,T本程序生成的目标代码如下:
七程序流程图编译程序流程图八实现本程序运行的硬件环境为CPU2GHZ,内存为4G.软件环境为windows8.1系统,VisualC+环境。
九程序运行结果1输入源文件路径:
2输出保留字3输出符号表的内容5输出语法分析的结果(本程序采用自下而上的LR语法分析)6输出中间代码7输出目标代码一十总结通过本次实验,对编译程序各阶段有了更深刻更深入的了解,也纠正了自己在某些方面的的错误,丰富了自己关于编译原理方面的知识。
同时也培养了自己热爱思考,勤查资料的习惯。
由于水平本次实验涉及面并不是很全面,我只考虑了c语言的一个子集。
当然本程序的算法在某些地方也还存在一些缺陷。
一十一附录(源程序)本程序输入的c源代码如下:
haominjie()a:
int;b:
int;ccc:
int;d:
int;ifcccbandcccathena=b+a;whilecccddoa=d;a=(b+ccc)*a+d本程序的完整源代码如下:
#include#include#include#include#include#includeusingnamespacestd;structtoken/词法token结构体intcode;/编码intnum;/递增编号token*next;token*token_head,*token_tail;/token队列structstr/词法string结构体intnum;/编号stringword;/字符串内容str*next;str*string_head,*string_tail;/string队列structivan/语法产生式结构体charleft;/产生式的左部stringright;/产生式的右部intlen;/产生式右部的长度;ivancss20;/语法20个产生式structpank/语法action表结构体charsr;/移进或归约intstate;/转到的状态编号;pankaction4618;/action表intgo_to4611;/语法go_to表structike/语法分析栈结构体,双链ike*pre;intnum;/状态intword;/符号编码ike*next;ike*stack_head,*stack_tail;/分析栈首尾指针structL/语义四元式的数据结构intk;stringop;/操作符stringop1;/操作数stringop2;/操作数stringresult;/结果L*next;/语义四元式向后指针L*Ltrue;/回填true链向前指针L*Lfalse;/回填false链向前指针;L*L_four_head,*L_four_tail,*L_true_head,*L_false_head;/*四元式链,true链,false链*/structsymb/语义输入时符号表stringword;/变量名称intaddr;/变量地址symb*next;symb*symb_head,*symb_tail;/语义符号链表/词法分析有关函数声明voidoutdaima();voidscan();/按字符读取源文件voidcifa_main();/词法分析主程序intjudge(charch);/判断输入字符的类型voidout1(charch);/写入token.txtvoidout3(charch,stringword);/写入string.txtvoidinput1(token*temp);/插入结点到队列tokenvoidinput3(str*temp);/插入结点到队列stringvoidoutput();/输出三个队列的内容voidoutfile();/输出三个队列的内容到相应文件中/语法分析有关函数声明voidyufa_main();/语法分析主程序voidyufa_initialize();/初始化语法分析数据结构intyufa_SLR1(inta);/语法分析主体部分intID1(inta);/给输入字符编号,转化成action表列编号stringID10(inti);/给输入字符反编号intID2(charch);/给非终结状态编号,转化成go_to表列编号intID20(charch);/给非终结状态编号charID21(intj);/给非终结状态反编号voidadd(ike*temp);/给ike分析栈链表增加一个结点voiddel();/给ike分析栈链表删除一个结点/语义分析相关函数的声明voidyuyi_main(intm);/语义分析主程序voidadd_L_four(L*temp);/向四元式链中加一个结点voidadd_L_true(L*temp);/向true链中加一个结点voidadd_L_false(L*temp);/向false链中加一个结点voidadd_symb(symb*temp);/向语义符号表链中加一个结点voidoutput_yuyi();/输出中间代码四元式和最后符号表stringnewop(intm);/把数字变成字符串stringid_numtoname(intnum);/把编号转换成相应的变量名intlookup(stringm);/变量声明检查/全局变量的声明FILE*fp;/文件指针intwordcount;/标志符计数interr;/标志词法分析结果正确或错误intnl;/读取行数intyuyi_linshi;/语义临时变量stringE_name,T_name,F_name,M_name,id_name,id1_name,id2_name,errword;/用于归约时名称传递和未声明变量的输出intid_num,id1_num,id2_num,id_left,id_while,id_then,id_do;/用于记录一些特殊的字符位置信息/主程序开始intmain()cout*endl;cout*说明:
*endl;cout*第一部分:
词法分析*endl;cout*第二部分:
语法分析*endl;cout*第三部分:
语义分析*endl;cout*第四部分:
目标代码生成*endl;cout*endl;cifa_main();/词法yufa_main();/语法output_yuyi();/语义outdaima();/代码生成coutnext=NULL;token_tail=newtoken;token_tail-next=NULL;string_head=newstr;string_head-next=NULL;string_tail=newstr;string_tail-next=NULL;/初始化三个队列的首尾指针L_four_head=newL;L_four_head-next=NULL;L_four_tail=newL;L_four_tail-k=0;L_four_tail-next=NULL;L_true_head=newL;L_true_head-Ltrue=NULL;L_false_head=newL;L_false_head-Lfalse=NULL;symb_head=newsymb;symb_head-next=NULL;symb_tail=newsymb;symb_tail-next=NULL;yuyi_linshi=-1;id_num=0;wordcount=0;/初始化字符计数器err=0;/初始化词法分析错误标志nl=1;/初始化读取行数scan();if(err=0)charm;output();cout词法分析正确完成!
endlendlm;coutendl;if(m=y)outfile();cout结果成功保存在token.txt和sting.txt两个文件中,请打开查看endl;coutendl;voidscan()coutendl;system(pause);coutendl;charch;stringword;chardocument50;intflag=0;coutdocument;coutendl;cout*endl;cout*第一部分:
词法分析*endl;cout*endl;if(fp=fopen(document,rt)=NULL)err=1;cout无法找到该文件!
endl;return;while(!
feof(fp)word=;ch=fgetc(fp);flag=judge(ch);if(flag=1)out1(ch);elseif(flag=3)out3(ch,word);elseif(flag=4|flag=5|flag=6)continue;elsecoutnl行错误:
非法字符!
ch|ch=:
|ch=;|ch=|ch=|ch=(|ch=)flag=1;/界符elseif(a=ch&ch=z)|(A=ch&ch:
id=4;break;case:
id=5;break;case;:
id=6;break;case:
id=7;break;case:
id=8;break;case(:
id=9;break;case):
id=10;break;/界符编码default:
id=0;token*temp;temp=newtoken;temp-code=id;temp-num=-1;temp-next=NULL;input1(temp);return;voidout3(charch,stringword)token*temp;temp=newtoken;temp-code=-1;temp-num=-1;temp-next=NULL;str*temp1;temp1=newstr;temp1-num=-1;temp1-word=;temp1-next=NULL;intflag=0;word=word+ch;ch=fgetc(fp);flag=judge(ch);if(flag=1|flag=4|flag=5|flag=6)if(word=and|word=if|word=then|word=while|word=do|word=int)if(word=and)temp-code=31;elseif(word=if)temp-code=32;elseif(word=then)temp-code=33;elseif(word=while)temp-code=35;elseif(word=do)temp-code=36;elseif(word=int)temp-code=37;/关键字编码input1(temp);if(flag=1)out1(ch);elseif(flag=4|flag=5|flag=6)return;elseif(flag=1)wordcount+;temp-code=25;temp-num=wordcount;input1(temp);temp1-num=wordcount;temp1-word=word;input3(temp1);out1(ch);elseif(flag=4|flag=5|flag=6)wordcount+;temp-code=25;temp-num=wordcount;input1(temp);temp1-num=wordcount;temp1-word=word;input3(temp1);return;elseif(flag=2|flag=3)out3(ch,word);/形成字符串elseerr=1;coutnl行错误:
非法字符!
chnext=NULL)token_head-next=temp;token_tail-next=temp;elsetoken_tail-next-next=temp;token_tail-next=temp;voidinput3(str*temp)if(string_head-next=NULL)string_head-next=temp;string_tail-next=temp;elsestring_tail-next-next=temp;string_tail-next=temp;voidoutput()couttoken表内容如下:
next;while(temp1!
=NULL)coutcode;if(temp1-num=-1)coutendl;elsecoutnumnext;cout符号表内容如下:
next;while(temp3!
=NULL)coutnumwordnext;voidoutfile()ofstreamfout1(token.txt);/写文件ofstreamfout3(string.txt);token*temp1;temp1=newtoken;temp1=token_head-next;while(temp1!
=NULL)fout1code;if(temp1-num=-1)fout1endl;elsefout1numnext;str*temp3;temp3=newstr;temp3=string_head-next;while(temp3!
=NULL)fout3numwordnext;/语法分析子程序voidyufa_main()if(err=0)system(pause);coutendl;cout*endl;cout*第二部分:
语法分析*endl;cout*next;intp,q;p=0;q=0;cout语法分析过程如下:
code);p=yufa_SLR1(w);if(p=1)break;if(p=0)temp=temp-next;if(temp=NULL)q=1;/语法分析if(q=1)while
(1)p=yufa_SLR1(17);if(p=3)break;/最后输入$来完成语法分析voidyufa_initialize()stack_head=newike;stack_tail=newike;stack_head-pre=NULL;stack_head-next=stack_tail;stack_head-num=0;stack_head-word=!
;stack_tail-pre=stack_head;stack_tail-next=NULL;/初始化栈分析链表css0.left=Q;css0.right=P;css1.left=P;css1.right=id()L;R;css2.left=L;css2.right=L;D;css3.left=L;css3.right=D;css4.left=D;css4.right=id:
int;css5.left=E;css5.right=E+T;css6.left=E;css6.right=T;css7.left=T;css7.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译器 编译 原理 课程设计 报告书