天津理工大学编译原理实验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:
:
vectoridentifier;
std:
:
vectorsource;
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:
:
vectorsymbolStack;//定义符号栈
std:
:
vectorinputStack;//定义输入栈
std:
:
vectorsemStack;//定义语义栈
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<<"";
}
心得体会:
这次实验做得还是不够理想,虽然做出了语法制导翻译的全过程,但是还有部分地方不够完美。
例如四元式的使用及输出,不过总体来说,也算是深入的掌握了语法制导翻译的全过程,获益匪浅。