编译方法实验报告中间代码生成器的设计.docx
《编译方法实验报告中间代码生成器的设计.docx》由会员分享,可在线阅读,更多相关《编译方法实验报告中间代码生成器的设计.docx(8页珍藏版)》请在冰豆网上搜索。
编译方法实验报告中间代码生成器的设计
编译方法实验报告
姓名
学号
班级
指导教师
实验名称
中间代码生成器的设计
开设学期
实验时间
第周
评定成绩
评定人签字
评定日期
2011年10月
•算术表达式文法:
G(E):
o0T|TTo1F|Fi|(E)
•文法变换:
G'(E)
T{F{i|(E)
coT}
dF}
•属性翻译文法:
T{F{i
o0“push(SYNw,)”T
o1“push(SYN,w)”
push(SEM,entry(w))
E
T
F
其中:
push(SYN,w)—当前单词w入算符栈SYN;push(SEM,entry(w))—当前w在符号表中的入口值压入语义栈SEM;
QUAT—生成四元式函数
i.T=newtemp;
ii.QT[j]=(SYN[k],SEM[s-1],SEM[s],T);j++;
iii.pop(SYN,_);pop(SEM,_);pop(SEM,_);push(SEM,T);
“QUAT”}
F“QUAT”}
”|(E)
熟悉算术表达式的语法分析与中间代码生成原理。
实验内容
实验原理及基本步骤
•递归下降子程序:
数据结构:
SYN—算符栈;
SEM—语义栈;
F
结束
出口
使用递归的结构进行四元式的设计,同时,运用堆栈结构将四元式的输出序列打印出来
//push(SYN,w)//read(w)
while(exp[i]=='+'||exp[i]=='-'){
syn[++i_syn]=exp[i];
i++;T();
quatO;}
//push(SYN,w)//read(w)
while(exp[i]=='*'||exp[i]==7'){
syn[++i_syn]=exp[i];
i++;F();
quat();}
voidquat(){
)");
strcpy(qt[j],"(,
//QT[j]:
=(SYN[k],SEM[s-1],SEM[s],temp);qt[j][1]=syn[i_syn];qt[j][3]=sem[i_sem-1];qt[j][5]=sem[i_sem];qt[j][7]=temp;
j++;
i_syn--;
i_sem--;
i_sem--;
sem[++i_sem]=temp;
temp++;}
//pop(SYN);
//pop(SEM);
//pop(SEM);
//push(SEM,temp);
五、
关键代码分析(带注释)及运行结果
#include
#include"string.h"
#include"stdio.h"
usingnamespacestd;
charsyn[10];
inti_syn;
charsem[10];
inti_sem;
charexp[50];
inti;
charqt[30][15];
intj=0;
chartemp='q';
intE();
intT();
intF();
voidquat();
intmain(intargc,char*argv[]){
printf("pleaseinputyourexpression:
");scanf("%s",exp);
i=0;
E();
if(exp[i]=='\0')
for(i=0;iprintf("%s\n",qt[i]);
//文法符号栈
//运算对象栈
//算术表达式区
//四元式区
//临时变量,取值为r--z
//生成四元式函数
//输入四元式
//read(w)
//输出四元式序列
else
printf("err");
return0;}
intE(){
T();
//push(SYN,w)
//read(w)
while(exp[i]=='+'||exp[i]=='-'){syn[++i_syn]=exp[i];i++;T();quat();}return1;}intT(){F();
//push(SYN,w)
//read(w)
//read(w)
while(exp[i]=='*'||exp[i]=='/'){syn[++i_syn]=exp[i];i++;F();quat();}return1;}intF(){if(exp[i]=='('){i++;E();if(exp[i]!
=')'){printf("err");return0;}
//push(SEM,w)
}elseif((exp[i]>='a'&&exp[i]<='p')||(exp[i]>='0'&&exp[i]<='9')){sem[++i_sem]=exp[i];}
//read(w)
else{printf("err");return0;}i++;return1;}voidquat(){
)");
strcpy(qt[j],"(,//QT[j]:
=(SYN[k],SEM[s-1],SEM[s],temp);
qt[j][1]=syn[i_syn];qt[j][3]=sem[i_sem-1];qt[j][5]=sem[i_sem];qt[j][7]=temp;
//pop(SYN);
//pop(SEM);
//pop(SEM);
//push(SEM,temp);
j++;i_syn--;i_sem--;i_sem--;
sem[++i_sem]=temp;
temp++;}
欝IcAscinputvDurcxprc-saion:
8■勺
|E'pocGBffi?
etupnedQexecutiontime:
13.542«
jh'r^ssanJIJc匕Vtocentinuc.
「*Q:
\PmgraTnfites\Ptagr*mrT>ablcPnc>groms\WorkSpflcc\<™fcblocks\'sryuons>ii\b!
'n\DrtMjg-..〔_三一一旦一迢
亡七£出inputexpHE$fi<^n:
2-l
Ffo七EE石petuivied0EHECut土antime:
376a
Egress日nyJc甘ytocentinus.
■n'"GAProgra-mrile^\PrograrnmablePrDgrami5\WairtSpac<\cQdeblocksXsiybianshi^binyDebug.^.邑_)
input占ion;3+*fi
^^pneoffBreturnedBexecutiantine二S.3D3ai'pnsBanyKeytocontinue.
八、
总结与分析
rRQcesspetuvnedQ^BxU^evecut'iontzne:
9ECVtsT'reaaan#keytocantInue.
七、
实验思考题
我们知道,定义一种语言除了要求定义语法外,还要求定义语义,即对语言的各种语法单位赋予具体的意义。
语义分析的任务是首先对每种语法单位进行静态的语义审查,然后分析其含义,并用另一种语言形式,即比源语言更加接近于目标语言的一种中间代码来进行描述这种语言。
因此,中间代码就显得十分重要,它关系着整个程序语言的正确编译与否,同时也是进行下一步编译的重要先决条件。
(1)
自顶向下法(推导法)
从开始符号出发,采用推导运算,试图自顶向下构造语法树。
自底向上法(归约法)
从给定的符号串出发,采用归约运算,试图自底向上构造语法树。
递归下降子程序法:
递归子程序法属于自顶向下语法分析方法。
故又名递
(2)
归下降法。
要求文法是LL
(1)文法。
LL
(1)分析法:
LL
(1)分析法是指从左到右扫描(第一个L)、最左推导(第二个L)和只查看一个当前符号(括号中的1)之意;LL
(1)分析法又称预测分析法,属于自顶向下确定性语法分析方法。
要求文法是LL
(1)文法。
(3)相同点:
都要求文法是LL
(1)文法;都是自顶向下的分析方法;都通过分析下个字符来判断该进入哪个状态或者调用哪个函数。
不同点:
LL
(1)分析法先建立起预测分析表,通过对分析栈的不断操作(出
栈,入栈)来进行;递归下降子程序法是通过函数间的函数调用来实现不同状态间的转换,并简化了代码。
(4)语法制导翻译是在语法分析过程中,随着分析(推导或归约)的逐步进展,每识别出一个语法结构,根据文法的每个规则所对应的语义子程序进行翻译的方法;核心技术是构造属性翻译文法。
5)假定:
SEM(m)--语义栈(属性传递、赋值场所);
QT[q]-四元式区;
G''(E):
E->T|E+T{GEQ(+)}|E-T{GEQ(-)}T->F|T*F{GEQ(*)}|
T/F{GEQ(/)}
F->i{PUSH(i)}|(E)
其中:
⑴PUSH(i)-压栈函数(把当前i压入语义栈);
⑵GEQ(w)-表达式四元式生成函数:
生成一个四元式送QT[q]过程:
1t:
=NEWT;{申请临时变量函数;}
2SEND(w,SEM[m-1],SEM[m],t)
3POP;POP;PUSH(t)