编译原理课程设计For语句的翻译程序设计简单优 先法输出三地址码.docx
- 文档编号:23884348
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:37
- 大小:94.63KB
编译原理课程设计For语句的翻译程序设计简单优 先法输出三地址码.docx
《编译原理课程设计For语句的翻译程序设计简单优 先法输出三地址码.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计For语句的翻译程序设计简单优 先法输出三地址码.docx(37页珍藏版)》请在冰豆网上搜索。
编译原理课程设计For语句的翻译程序设计简单优先法输出三地址码
学号:
0121410870922
课程设计
课程
编译原理
题目
For语句的翻译程序设计(简单优先法、输出三地址码)
学院
计算机科学与技术学院
专业
计算机科学与技术
班级
计算机1404
姓名
王承禹
指导教师
林泓
2016
年
12
月
27
日
目录
1系统描述2
1.1设计目的2
1.2设计内容描述2
2文法及属性文法的描述2
3语法分析方法描述及语法分析表设计3
3.1语法分析方法描述3
3.2分析法操作步骤4
3.3优先关系矩阵5
4中间代码形式的描述及中间代码序列的结构设计5
4.1中间代码形式5
5编译系统的概要设计6
5.1数据结构6
5.2模块设计6
5.2.1词法分析模块7
5.2.2语法、语义分析模块7
5.2.3主控模块11
6详细的算法描述11
6.1词法分析算法11
6.2语法分析算法12
6.3语义分析算法12
7软件的测试方法和测试结果13
8本设计的评价、特点、14
9收获与体会14
10核心代码16
成绩评定表27
For语句的翻译程序设计
(简单优先法、输出三地址码)
1系统描述
1.1设计目的
通过学习编译原理的相关内容,设计并编写FOR循环语句的翻译程序,使用简单优先法,按三地址码输出,能够实现词法分析,语法和语义的分析,加深对所学知识的理解,并且能够熟练运用到实际当中。
1.2设计内容描述
FOR循环语句的基本格式如下:
FORi=EstepEuntilEdoStmt
根据所给题目要求,设计出符合FOR循环语句的文法及属性文法的描述,语法分析方法以及三地址码的输出方式,罗列出词法分析和语法分析的流程,根据语法规则设计输入输出方法,简单优先法中的优先关系表格。
设计好并且进行编译,设计若干输入输出用例(包括正确的输入和错误的输入,用来检查程序的完整性)。
2文法及属性文法的描述
根据For语句的特点,制定的产生式规则及由产生式对应的语义动作如下:
F1->fori=E1
{emit(entry(i),'=',E1.place);
F1.place=entry(i);/*保存控制变量在符号表中的位置*/
F1.chain=nextstat;
emit('goto'--);/*gotoOVER*/
F1.codebegin=nextstat;/*保存AGAIN的地址*/}
F2->F1stepE2
{F2.codebegin=F1.codebegin;
F2.place=F1.place;
emit(F1.place'='E2.place'+'F1.place);
backatch(F1.chain,nextstat);}
F3->F2untilE3
{F3.codebegin=F2.codebegin;
q=nextstat;
emit('if'F2.place,'<='E3.place,'goto'q+2);
/*若i<=E3转去执行循环体的第一个三地址码*/
F3.chain=nextstat;
emit('goto'--)/*转离循环*/}
S->F3doStmt
{emit('goto'F3.codebegin)/*gotoAGAIN*/
backpatch(Stmt.chain,F3.codebegin);
Stmt.chain=F3.chain/*转离循环的转移目标留待外层S时再回填*/}
3语法分析方法描述及语法分析表设计
3.1语法分析方法描述
本次课内实践要求使用简单优先关系方法。
简单优先分析法的基本思想史对一个文法按照一定原则求出该文法所有符号即包括终结符和非终结符之间的优先关系确定归约过程中的句柄,它的归约实际上是一种规范归约。
一个文法是简单优先文法必须满足以下条件
(1)在文法符号集V中,任意两个符号之间最多只有一种优先关系成立;
(2)在文法中任意两个产生式没有相同的右部。
三种优先关系及其判定方法如下所示:
(1)X=Y表示X和Y的优先关系相等,当且仅当G中存在产生式规则A→…XY…;
(2)X A→…XB…,且B Y…; (3)X>Y表示X的优先性比Y的优先性大,当且仅当G中存在产生式规则 A→…BD…,且B …X和D Y…; (4)对任何X,若文法开始符号S→X…,则# 3.2分析法操作步骤 (1)由简单优先分析法的基本思想设计的如下算法,首先要构造优先关系矩阵(如3.3所示),并将文法产生式保存,设置符号数组S: (2)将输入符号串a1a2…an#依次逐个保存符号数组S中,直到遇到数组中第一个符号ai的优先性>下一个待输入符号aj为止。 (3)数组当前符号ai为句柄尾,由此向左在数组中找句柄的头符号ak,即找到ak-1 由句柄ak…ai在文法的产生式中查找右部为ak…ai的产生式,若找到则用相应左部代替句柄,找不到则为出错,这是可断定输入串不是该文法的句子。 重复 (1) (2)(3),直到归约完输入符号串,数组中只剩文法的开始符号为止。 3.3优先关系矩阵 F1 F2 F3 for i = E step until do Stmt # F1 = F2 = F3 for = i = = = E > > > step = until = do < < < < Stmt # 图3.3优先关系矩阵 4中间代码形式的描述及中间代码序列的结构设计 4.1中间代码形式 三地址码是由下面一般形式的语句构成的序列: x: =yopz 其中,xyz为名字、常数或变量;op代表运算符。 对于本程序的具体三地址码输出,预计显示结果如下: 给定输入程序fori=0step1until10do{j=b+c;} 三地址码输出为 <1>i=0 <2>goto<5> <3>i++ <4>ifi<10goto<5>elsegoto<7> <5>j=b+c <6>goto<3> <7>end 5编译系统的概要设计 5.1数据结构 单词种别: structToken { //单词种别 intnum; //词素(单词的值) stringlexeme; }; 产生式结构: structTerm { //1为状态,2为产生式 intkind; //如果是状态保存格子里的内容 stringaction; }; 5.2模块设计 本系统分为四大模块: 词法分析模块、语法分析模块、语义分析模块以及主控模块,其中主控模块负责协调前三个模块。 词法分析模块为语法分析模块以及语义分析模块提供单词序列。 5.2.1词法分析模块 voidLexicalScanner() { //词法分析 FILE*fp; charch; errno_t_err2=fopen_s(&fp,"d: \\123.txt","rb"); if(fp==NULL) //取当前目录下的tk.txt文件的第一个字符 { fprintf(stderr,"erroropening! \n"); //格式化输出到流 //错误打印到屏幕上 exit (1); } do{ ch=fgetc(fp); if(ch=='$') break; //作为文件结尾 elseif(ch=='') scanner(fp); //空格略过 else { fseek(fp,-1,1); scanner(fp); } //扫描 }while(ch! ='$'); strings[arrTop]="(1,$)"; } 5.2.2语法、语义分析模块 voidSemantic() { Tokent1; t1.lexeme="#"; t1.num=100; tokens[tokenTop]=t1; for(inti=0;i<20;i++) { cout< } cout< stringproduct1="fori=E1"; stringproduct2="F1stepE2"; stringproduct3="F2untilE3"; stringproduct4="F3doS1"; stack for(inti=0;i<15;i++) { for(intj=0;j<15;j++) { priorityTable[i][j]=2; } } tokenStack.push("#"); map_.insert(map : value_type("S",0)); map_.insert(map : value_type("F1",1)); map_.insert(map : value_type("F2",2)); map_.insert(map : value_type("F3",3)); map_.insert(map : value_type("for",4)); map_.insert(map : value_type("step",5)); map_.insert(map : value_type("until",6)); map_.insert(map : value_type("do",7)); map_.insert(map : value_type("i",8)); map_.insert(map : value_type("=",9)); map_.insert(map : value_type("E1",10)); map_.insert(map : value_type("E2",11)); map_.insert(map : value_type("E3",12)); //map_.insert(map : value_type("#",13)); map_.insert(map : value_type("S1",13)); map_.insert(map : value_type("#",14)); priorityTable[map_["for"]][map_["i"]]=0; priorityTable[map_["i"]][map_["="]]=0; priorityTable[map_["="]][map_["E1"]]=0; priorityTable[map_["F1"]][map_["step"]]=0; priorityTable[map_["step"]][map_["E2"]]=0; priorityTable[map_["F2"]][map_["until"]]=0; priorityTable[map_["until"]][map_["E3"]]=0; priorityTable[map_["F3"]][map_["do"]]=0; priorityTable[map_["do"]][map_["S1"]]=0; priorityTable[map_["do"]][map_["F3"]]=-1; priorityTable[map_["do"]][map_["F2"]]=-1; priorityTable[map_["do"]][map_["F1"]]=-1; priorityTable[map_["do"]][map_["for"]]=-1; priorityTable[map_["#"]][map_["S"]]=-1; priorityTable[map_["#"]][map_["F1"]]=-1; priorityTable[map_["#"]][map_["F2"]]=-1; priorityTable[map_["#"]][map_["F3"]]=-1; priorityTable[map_["#"]][map_["for"]]=-1; priorityTable[map_["E1"]][map_["step"]]=1; priorityTable[map_["E2"]][map_["until"]]=1; priorityTable[map_["E3"]][map_["do"]]=1; priorityTable[map_["S"]][map_["#"]]=1; for(inti=0;i<15;i++) { for(intj=0;j<15;j++) { cout< } cout< } inti=0; while(strcmp("#",tokens[i].lexeme.c_str())! =0) { while(priorityTable[map_[tokenStack.top()]][map_[tokens[i].lexeme.c_str()]]<1) { tokenStack.push(tokens[i].lexeme); //cout< i++; } if(priorityTable[map_[tokenStack.top()]][map_[tokens[i].lexeme.c_str()]]==2&&! strcmp(tokens[i].lexeme.c_str(),"")) { cout<<"error"< system("pause"); //error } else { //cout<<"enter"< stringtempStr=""; stringtop=tokenStack.top(); tempStr=tokenStack.top()+tempStr; tokenStack.pop(); while(priorityTable[map_[tokenStack.top()]][map_[top]]==0) { top=tokenStack.top(); tempStr=top+tempStr; tokenStack.pop(); //cout< } if(priorityTable[map_[tokenStack.top()]][map_[top]]==2) { //error cout<<"error2"< system("pause"); } else { if(! strcmp(tempStr.c_str(),product1.c_str())) { tokenStack.push("F1"); cout<<"i=E1"< cout<<"gotoOVER"< } if(! strcmp(tempStr.c_str(),product2.c_str())) { tokenStack.push("F2"); cout<<"AGAIN: i=i+E2"< } if(! strcmp(tempStr.c_str(),product3.c_str())) { tokenStack.push("F3"); cout<<"OVER: ifi } if(! strcmp(tempStr.c_str(),product4.c_str())) { tokenStack.push("S"); cout<<"beginS1;"< } } //cout< } //tokenStack.push(tokens[i].lexeme); //i++; } } 5.2.3主控模块 intmain() { File.open("d: \\1233.txt",ios: : out); //词法分析 LexicalScanner(); //词法分析完成后会将Token序列输出到中间文件 //语法分析 SyntaxScanner(); //语义分析 Semantic(); File.close(); cout< return0; } 6详细的算法描述 6.1词法分析算法 6.2语法分析算法 6.3语义分析算法 语法分析与语义分析同步完成,在规约的过程中,每使用一个产生式则调用其对应的动作 7软件的测试方法和测试结果 编译调试环境: VisualStudio2015Community 程序语言: C++ 测试用例: 采用如下形式双重循环作为测试用例之一 首先输出的是词法分析结果: 然后是语法以及语义分析结果: 8本设计的评价、特点、 本系统可以完成Fortran语言的For语句的语法制导翻译,在词法分析的基础上先后进行语法分析和语义分析。 在完成这些功能的基础上,我认为此系统仍然不能算一个合格的产品,还有很多需要改进之处。 例如,词法分析可以进一步改进成为词法分析器的自动生成器。 语法分析和语义分析也应改为自动生成简单优先文法生成器。 特点: 本系统可以完成Fortran语言的子集(For语句)的制导翻译,但是没有优化过程,符号表的控制也很简单,很多代码采用了硬编的方法,改变文法将导致巨大的工作量。 因此本系统的一大特点是不易扩展和变更。 9收获与体会 经过这次课内实践,使我更加扎实的掌握了有关编译原理方面的知识,在编写程序的过程中遇到了许多问题,但经过一遍遍的调试终于使得程序可以顺利运行。 但是程序中存在着很大的不足: 程序可扩展性差。 过而能改,善莫大焉。 在课内过程中,我不断发现错误,不断改正,不断领悟,不断获取。 最终的检测调试环节,本身就是在践行“过而能改,善莫大焉”的知行观。 这次课内实践终于顺利完成了,在设计中遇到了很多问题,最后终于游逆而解。 在今后发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永远不可能得到社会及他人对你的认可! 回顾这次课内实践,是一个痛并快乐的过程,在构造简单优先文法的矩阵时遇到了不少困难,花费了许多时间,但是当成功构造出来时那种喜悦也是难以言表的。 学习是个不断提升自我的过程。 10核心代码 #include"stdafx.h" #include #include #include #include #include #include #include #include #include #include #include usingnamespacestd; //定义图,字符串与数字下表对应 map //定义优先级表-1为小于,0为等于,1为大于 intpriorityTable[15][15]; //Tokenstructure structToken { //单词种别 intnum; //词素(单词的值) stringlexeme; }; structTerm { //1为状态,2为产生式 intkind; //如果是状态保存格子里的内容 stringaction; }; classSyntaxScanner { public: SyntaxScanner(); ~SyntaxScanner(); voidcreateTable()//movetoProduct2DAFMachine { } boolScanner() { } private: stack stack TermAc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译原理课程设计For语句的翻译程序设计简单优 先法输出三地址码 编译 原理 课程设计 For 语句 翻译 程序设计 简单 输出 地址