天津理工大学编译原理实验3语义分析与中间代码生成.docx
- 文档编号:5945567
- 上传时间:2023-01-02
- 格式:DOCX
- 页数:21
- 大小:132.70KB
天津理工大学编译原理实验3语义分析与中间代码生成.docx
《天津理工大学编译原理实验3语义分析与中间代码生成.docx》由会员分享,可在线阅读,更多相关《天津理工大学编译原理实验3语义分析与中间代码生成.docx(21页珍藏版)》请在冰豆网上搜索。
天津理工大学编译原理实验3语义分析与中间代码生成
实验报告
学院(系)名称:
计算机与通信工程学院
姓名
*****
学号
*****
专业
计算机科学与技术
班级
*****
实验项目
实验三:
语义分析与中间代码生成
课程名称
编译原理
课程代码
0668056
实验时间
*******
实验地点
计算机软件实验室7-219
批改意见
成绩
教师签字:
实验内容:
可选择LL1分析法、算符优先分析法、LR分析法之一,实现如下表达式文法的语法制导翻译过程。
文法G[E]如下所示:
E→E+T|E-T|T
T→T*F|T/F|F
F→P^F|P
P→(E)|i
要求构造出符合语义分析要求的属性文法描述,并在完成实验二(语法分析)的基础上,进行语义分析程序设计,最终输出与测试用例等价的四元式中间代码序列。
实验目的:
1.掌握语法制导翻译的基本功能。
2.巩固对语义分析的基本功能和原理的认识。
3.能够基于语法制导翻译的知识进行语义分析。
4.掌握类高级语言中基本语句所对应的语义动作。
5.理解并处理语义分析中的异常和错误。
实验要求:
1.在实验二的基础上,实现语法制导翻译功能,输出翻译后所得四元式序列;
2.要求详细描述所选分析方法进行制导翻译的设计过程;
3.完成对所设计分析器的功能测试,并给出测试数据和实验结果;
4.为增加程序可读性,请在程序中进行适当注释说明;
5.整理上机步骤,总结经验和体会;
6.认真完成并按时提交实验报告。
【实验过程记录(源程序、测试用例、测试结果及心得体会等)】
分析的四元式:
(+,E1.place,T.place,E.place)
(-,E1.place,T.place,E.place)
(=,T.place,_,E.place)
(*,T1.place,F.place,T.place)
(/,T1.place,F.place,T.place)
(=,F.place,_,T.place)
(^,P.place,_,F.place)
(=,P.place,_,F.place)
(=,E.place,_,P.place)
(=,lookup(i.name),_,P.place)
根据语法分析修改的程序流程图
程序运行结果:
部分源代码:
Main.cpp
#include
#include"Syntax.h"
intmain(intargc,char**argv)
{
std:
:
stringsource;
std:
:
cout<<"pleaseinputanarithmeticexpression"< : endl; std: : cin>>source; ccyg: : Syntax*syn=newccyg: : Syntax(source); syn->analysis(); std: : cout<<"symbolStack: "<<"inputStack: "<<"semStack: "< : endl; while(! syn->getSuccess()) { syn->printSymbol(); syn->printSource(); syn->printSemantic(); syn->nextStep(); std: : cout< : endl; } deletesyn; system("pause"); } Lexical.h #pragmaonce #include #include namespaceccyg { classLexical { public: enumletter { add=0, sub=1, mul=2, div=3, pow=4, ide=5, lef=6, rig=7, sha=8 }; Lexical(); Lexical(std: : string); ~Lexical(); boolanalysis(); voidprintSource(); voidsetSourceCode(std: : string); chartoChar(int); std: : vector std: : vector private: std: : stringsourceCode; }; } Lexical.cpp #include"Lexical.h" #include #include usingnamespaceccyg; Lexical: : Lexical() { } Lexical: : Lexical(std: : strings) { sourceCode=s; } Lexical: : ~Lexical() { } boolLexical: : analysis() { if(sourceCode.size()==0) { std: : cout<<"sourceisempty! "< : endl; returnfalse; } source.clear(); identifier.clear(); intnumber=NULL; for(inti=0;i<=sourceCode.size();i++) { if(i==sourceCode.size()) { if(number! =NULL) { source.push_back(ide); identifier.push_back(number); number=0; } source.push_back(sha); returntrue; } elseif(sourceCode[i]>='0'&&sourceCode[i]<='9') { number=number*10+sourceCode[i]-48; } else { if(number! =NULL) { source.push_back(ide); identifier.push_back(number); number=0; } switch(sourceCode[i]) { case'+': source.push_back(add); break; case'-': source.push_back(sub); break; case'*': source.push_back(mul); break; case'/': source.push_back(div); break; case'^': source.push_back(pow); break; case'(': source.push_back(lef); break; case')': source.push_back(rig); break; default: std: : cout<<"cannotidentify: "< : endl; returnfalse; break; } } } source.push_back(sha); returntrue; } voidLexical: : printSource() { for(inti=0;i { std: : cout< } std: : cout<<""; } charLexical: : toChar(inta) { switch(a) { caseadd: return'+'; casesub: return'-'; casemul: return'*'; casediv: return'/'; casepow: return'^'; caseide: return'i'; caselef: return'('; caserig: return')'; casesha: return'#'; default: break; } return0; } voidLexical: : setSourceCode(std: : stringsource) { sourceCode=source; } Syntax.h #pragmaonce #include"Lexical.h" namespaceccyg { classSyntax: publicccyg: : Lexical { public: enumRelation//定义优先关系枚举 { equal=0, less=1, greater=2, //错误 i_i=3, i_left=4, left_sharp=5, right_i=6, right_left=7, sharp_right=8 }; enumSymbol { E=9, T=10, F=11, P=12 }; Syntax(std: : string=0); ~Syntax(); boolreduced();//定义归约方法 voidmovein();//定义移进方法 intfindOperator();//查找最近运算符 chartoChar(int); boolnextStep(); voidinitNext(); voidprintSymbol(); voidprintSemantic(); boolgetSuccess(); std: : vector std: : vector std: : vector boolisSuccess; boolisInitNext; staticconstintpreArray[9][9]; }; } Syntax.cpp #include"Syntax.h" #include usingnamespaceccyg; constintSyntax: : preArray[9][9]={2,2,1,1,1,1,1,2,2, 2,2,1,1,1,1,1,2,2, 2,2,2,2,1,1,1,2,2, 2,2,2,2,1,1,1,2,2, 2,2,2,2,2,1,1,2,2, 2,2,2,2,2,3,4,2,2, 1,1,1,1,1,1,1,0,5, 2,2,2,2,2,6,7,2,2, 1,1,1,1,1,1,1,8,0}; longlongpoow(inta,intb) { if(b==1) { returna; } else { returnpoow(a,b-1)*a; } } Syntax: : Syntax(std: : strings): Lexical(s) { isSuccess=false; isInitNext=false; } Syntax: : ~Syntax() { } voidSyntax: : movein() { symbolStack.push_back(source[0]); if(source[0]==ide) { semStack.push_back(identifier[0]); std: : vector : iteratoriter=identifier.begin(); identifier.erase(iter); } else { semStack.push_back(NULL); } std: : vector : iteratorit=source.begin(); source.erase(it); } boolSyntax: : reduced() { if(symbolStack[symbolStack.size()-1]==ide) { symbolStack[symbolStack.size()-1]=P; } else { switch(symbolStack[symbolStack.size()-2]) { caseadd: { symbolStack[symbolStack.size()-3]=E; symbolStack.pop_back(); symbolStack.pop_back(); semStack[semStack.size()-3]=semStack[semStack.size()-3]+semStack[semStack.size()-1]; semStack.pop_back(); semStack.pop_back(); break; } casesub: { symbolStack[symbolStack.size()-3]=E; symbolStack.pop_back(); symbolStack.pop_back(); semStack[semStack.size()-3]=semStack[semStack.size()-3]-semStack[semStack.size()-1]; semStack.pop_back(); semStack.pop_back(); break; } casemul: { symbolStack[symbolStack.size()-3]=T; symbolStack.pop_back(); symbolStack.pop_back(); semStack[semStack.size()-3]=semStack[semStack.size()-3]*semStack[semStack.size()-1]; semStack.pop_back(); semStack.pop_back(); break; } casediv: { symbolStack[symbolStack.size()-3]=T; symbolStack.pop_back(); symbolStack.pop_back(); semStack[semStack.size()-3]=(double)semStack[semStack.size()-3]/(double)semStack[semStack.size()-1]; semStack.pop_back(); semStack.pop_back(); break; } casepow: { symbolStack[symbolStack.size()-3]=F; symbolStack.pop_back(); symbolStack.pop_back(); semStack[semStack.size()-3]=poow(semStack[semStack.size()-3],semStack[semStack.size()-1]); semStack.pop_back(); semStack.pop_back(); break; } caselef: { symbolStack[symbolStack.size()-2]=E; symbolStack.pop_back(); semStack[semStack.size()-2]=semStack[semStack.size()-1]; semStack.pop_back(); std: : vector : iteratorit=source.begin(); source.erase(it); break; } casesha: { std: : cout<<"analysissuccess"< : endl; returntrue; break; } } } returnfalse; } intSyntax: : findOperator() { for(inti=symbolStack.size()-1;i>=0;i--) { if(symbolStack[i] { returnsymbolStack[i]; } } return-1; } charSyntax: : toChar(inti) { charch=Lexical: : toChar(i); if(ch! =0) { returnch; } switch(i) { caseE: { return'E'; } caseT: { return'T'; } caseF: { return'F'; } caseP: { return'P'; } default: { std: : cout<<"error: unknownsymbol"< : endl; } } return0; } voidSyntax: : initNext() { if(isInitNext==false) { symbolStack.clear(); symbolStack.push_back(sha); semStack.clear(); semStack.push_back(NULL); isSuccess=false; isInitNext=true; } } boolSyntax: : nextStep() { if(isSuccess==true) { returntrue; } if(! isInitNext) { initNext(); } inta=findOperator(); intb=source[0]; switch(preArray[a][b]) { caseless: { movein(); break; } casegreater: { reduced(); break; } caseequal: { isSuccess=reduced(); break; } } returnisSuccess; } voidSyntax: : printSymbol() { for(inti=0;i { std: : cout< } std: : cout<<""; } boolSyntax: : getSuccess() { returnisSuccess; } voidSyntax: : printSemantic() { for(inti=0;i { if(semStack[i]==NULL) { std: : cout<<'_'; } else { std: : cout< } } std: : cout<<""; } 心得体会: 这次实验做得还是不够理想,虽然做出了语法制导翻译的全过程,但是还有部分地方不够完美。 例如四元式的使用及输出,不过总体来说,也算是深入的掌握了语法制导翻译的全过程,获益匪浅。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 天津 理工大学 编译 原理 实验 语义 分析 中间 代码 生成