编译原理实验二zy.docx
《编译原理实验二zy.docx》由会员分享,可在线阅读,更多相关《编译原理实验二zy.docx(13页珍藏版)》请在冰豆网上搜索。
![编译原理实验二zy.docx](https://file1.bdocx.com/fileroot1/2022-12/14/41a03419-f94d-46b1-878b-7a99ac2092d0/41a03419-f94d-46b1-878b-7a99ac2092d01.gif)
编译原理实验二zy
实验二 语法分析及语义处理实验
专业:
13计算机一班学号:
20130610040109姓名:
赵宇
一、【实验目的】
加深对语法分析器工作过程的理解;能够采用一种编程语言实现简单的语义分析程序;能够使用自己编写的分析程序对简单的程序段进行语义分析,生成中间代码。
二、【实验内容】
1.掌握递归子程序(或过程)的设计方法。
2.掌握用递归子程序法设计语法分析的方法,从而加深对其他方法的理解。
3.掌握目标程序的运行方法,掌握各源程序语句的目标结构。
4.掌握以语法为主导的翻译方法。
5.用递归下降分析法编制语义分析程序。
三、【实验要求】
1.对语法规则有明确的定义;
2.编写的分析程序能够对输入算数表达式进行正确的语义分析;
3.对于遇到的语法、语义错误,能够做出简单的错误处理,给出简单的错误提示,保证语义分析过程;
4.实验报告要求用文法的形式对语义详细说明,说明语义分析程序的工作过程,说明相应翻译动作的实现。
四、【实验步骤】
1.定义语法规则;
2.设置语义过程,插入语义动作;
3.对遇到的语法、语义错误做出错误处理。
五、【算法思想】
1、算术表达式的定义
算术表达式的文法:
〈无符号整数〉∷=〈数字〉{〈数字〉}
〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}
〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉}
〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}
〈因子〉∷=〈标志符〉|〈无符号整数〉
〈加法运算符〉∷=+|-
〈乘法运算符〉∷=*|/
〈字母〉∷=a|b|…|z
〈数字〉∷=0|1|…|9
2、构造出相应的文法
E->TE~
E~->+TE~
E~->-TE~
E~->&
T->FT~
T~->*FT~
T~->\FT~
T~->&
F->(E)
F->n
F->z
n表示数字z表示字符
3、设置语义过程。
(1)emit(char*result,char*ag1,char*op,char*ag2)
该函数的功能是生成一个三地址语句送到四元式表中。
四元式表的结构如下:
struct
{charresult[8];
charag1[8];
charop[8];
charag2[8];
}quad[20];
(2)char*newtemp()
该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,…
char*newtemp(void)
{char*p;
charm[8];
p=(char*)malloc(8);
k++;
itoa(k,m,10);
strcpy(p+1,m);
p[0]=’t’;
return(p);
}
4、函数intlrparser()
在原来语法分析的基础上插入相应的语义动作:
将输入串翻译成四元式序列。
在实验中我们只对表达式、赋值语句进行翻译。
5、函数voidscaner()
扫描表达式进行词法分析
6、函数char*expression_r(void)
对加减法进行语义分析,调用term分析产生表达式计算的第一项eplace,调用term分析产生表达式计算的第二项ep2,调用newtemp产生临时变量tp存储计算结果,生成四元式送入四元式表。
7、函数char*term(void)
对乘除进行语义分析,调用factor()分析产生表达式计算的第一项eplace,调用factor分析产生表达式计算的第二项ep2,调用newtemp产生临时变量tp存储计算结果,生成四元式送入四元式表。
8、函数char*factor(void)
对于赋值语句进行语法分析,并返回对应表达式中三元式的地址。
六、【源程序代码】
#include
#include
#include
#include
struct
{
charresult[12];
charag1[12];
charop[12];
charag2[12];
}quad;
charprog[80],token[12];
charch;
intsyn,p,m=0,n,sum=0,kk;//p是缓冲区prog的指针,m是token的指针
char*rwtab[6]={"begin","if","then","while","do","end"};
voidscaner();
char*factor(void);
char*term(void);
char*expression_r(void);
intyucu();
voidemit(char*result,char*ag1,char*op,char*ag2);
char*newtemp();
intstatement();
intk=0;
voidemit(char*result,char*ag1,char*op,char*ag2)
{
strcpy(quad.result,result);
strcpy(quad.ag1,ag1);
strcpy(quad.op,op);
strcpy(quad.ag2,ag2);
cout<}
char*newtemp()
{
char*p;
charm[12];
p=(char*)malloc(12);
k++;
itoa(k,m,10);
strcpy(p+1,m);
p[0]='t';
return(p);
}
voidscaner()
{
for(n=0;n<8;n++)
token[n]=NULL;
ch=prog[p++];
while(ch=='')
{
ch=prog[p];
p++;
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{m=0;
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
p--;
syn=10;
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0){
syn=n+1;
break;
}
}
elseif((ch>='0'&&ch<='9'))
{
sum=0;
while((ch>='0'&&ch<='9')){
sum=sum*10+ch-'0';
ch=prog[p++];
}
p--;
syn=11;
if(sum>32767)
syn=-1;
}
elseswitch(ch)
{
case'<':
m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='>'){
syn=21;
token[m++]=ch;
}
elseif(ch=='='){
syn=22;
token[m++]=ch;
}
else{
syn=23;
p--;
}
break;
case'>':
m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='='){
syn=24;
token[m++]=ch;
}
else{
syn=20;
p--;
}
break;
case':
':
m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='='){
syn=18;
token[m++]=ch;
}
else{
syn=17;
p--;
}
break;
case'*':
syn=13;token[0]=ch;break;
case'/':
syn=14;token[0]=ch;break;
case'+':
syn=15;token[0]=ch;break;
case'-':
syn=16;token[0]=ch;break;
case'=':
syn=25;token[0]=ch;break;
case';':
syn=26;token[0]=ch;break;
case'(':
syn=27;token[0]=ch;break;
case')':
syn=28;token[0]=ch;break;
case'#':
syn=0;token[0]=ch;break;
default:
syn=-1;break;
}
}
intlrparser()
{//cout<<"调用lrparser"<intschain=0;
kk=0;
if(syn==1){
scaner();
schain=yucu();
if(syn==6){
scaner();
if(syn==0&&(kk==0))
cout<<"success!
"<}
else{
if(kk!
=1)
cout<<"缺end!
"<kk=1;
}
}
else
{cout<<"缺begin!
"<return(schain);
}
intyucu()
{//cout<<"调用yucu"<intschain=0;
schain=statement();
while(syn==26){
scaner();
schain=statement();
}
return(schain);
}
intstatement()
{//cout<<"调用statement"<char*eplace,*tt;
eplace=(char*)malloc(12);
tt=(char*)malloc(12);
intschain=0;
switch(syn){
case10:
strcpy(tt,token);
scaner();
if(syn==18){
scaner();
strcpy(eplace,expression_r());
emit(tt,eplace,"","");
schain=0;
}
else{
cout<<"缺少赋值符!
"<kk=1;
}
return(schain);
break;
}
return(schain);
}
char*expression_r(void)
{
char*tp,*ep2,*eplace,*tt;
tp=(char*)malloc(12);
ep2=(char*)malloc(12);
eplace=(char*)malloc(12);
tt=(char*)malloc(12);
strcpy(eplace,term());//调用term分析产生表达式的第一项eplace
while((syn==15)||(syn==16)){
if(syn==15)strcpy(tt,"+");
elsestrcpy(tt,"-");
scaner();
strcpy(ep2,term());//调用term分析产生表达式的第二项ep2
strcpy(tp,newtemp());//调用newtemp产生临时变量tp存储结果
emit(tp,eplace,tt,ep2);//生成四元式送入四元式表
strcpy(eplace,tp);
}
return(eplace);
}
char*term(void)
{//cout<<"调用term"<char*tp,*ep2,*eplace,*tt;
tp=(char*)malloc(12);
ep2=(char*)malloc(12);
eplace=(char*)malloc(12);
tt=(char*)malloc(12);
strcpy(eplace,factor());
while((syn==13)||(syn==14)){
if(syn==13)strcpy(tt,"*");
elsestrcpy(tt,"/");
scaner();
strcpy(ep2,factor());/调用factor分析产生表达式的第二项ep2
strcpy(tp,newtemp());//调用newtemp产生临时变量tp存储结果
emit(tp,eplace,tt,ep2);//生成四元式送入四元式表
strcpy(eplace,tp);
}
return(eplace);
}
char*factor(void)
{
char*fplace;
fplace=(char*)malloc(12);
strcpy(fplace,"");
if(syn==10){
strcpy(fplace,token);//将标识符token的值赋给fplace
scaner();
}
elseif(syn==11){
itoa(sum,fplace,10);
scaner();
}
elseif(syn==27){
scaner();
fplace=expression_r();//调用expression分析返回表达式的值
if(syn==28)
scaner();
else{
cout<<"缺)错误!
"<kk=1;
}
}
else{
cout<<"缺(错误!
"<kk=1;
}
return(fplace);
}
voidmain()
{
p=0;
cout<<"**********语义分析程序**********"<cout<<"Pleaseinputstring:
"<do{
cin.get(ch);
prog[p++]=ch;
}
while(ch!
='#');
p=0;
scaner();
lrparser();
}
七、【结果验证】
(a)给定源程序
begina:
=2+3*4;x:
=(a+b)/cend#
输出结果
**********语义分析程序**********
Pleaseinputstring:
begina:
=2+3*4;x:
=(a+b)/cend#
t1=3*4
t2=2+t1
a=t2
t3=a+b
t4=t3/c
x=t4
success!
(b)源程序
begina:
=9;x:
=2*3-1;b:
=(a+x/2end#
输出结果
**********语义分析程序**********
Pleaseinputstring:
begina:
=9;x:
=2*3-1;b:
=(a+x/2end#
a=9
t1=2*3
t2=t1-1
x=t2
t3=x/2
t4=a+t3
缺)错误!
b=t4