实验3 语义分析实验报告
一、 实验目的
通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。
二、 实验要求
采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。
三、 算法思想
1、设置语义过程。
(1)emit(char *result,char *ag1,char *op,char *ag2)
该函数的功能是生成一个三地址语句送到四元式表中。
四元式表的结构如下:
struct
{ char result[8];
char ag1[8];
char op[8];
char ag2[8];
}quad[20];
(2) char *newtemp()
该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,…
char *newtemp(void)
{ char *p;
char m[8];
p=(char *)malloc(8);
k++;
itoa(k,m,10);
strcpy(p+1,m);
p[0]=’t’;
return(p);
}
2、函数lrparser 在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。在实验中我们只对表达式、赋值语句进行翻译。
四、 源程序代码:
#include<stdio.h>
#include<string.h>
#include<iostream.h>
#include<stdlib.h>
struct
{
char result[12];
char ag1[12];
char op[12];
char ag2[12];
}quad;
char prog[80],token[12];
char ch;
int syn,p,m=0,n,sum=0,kk; //p是缓冲区prog的指针,m是token的指针
char *rwtab[6]={"begin","if","then","while","do","end"};
void scaner();
char *factor(void);
char *term(void);
char *expression(void);
int yucu();
void emit(char *result,char *ag1,char *op,char *ag2);
char *newtemp();
int statement();
int k=0;
void emit(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<<quad.result<<"="<<quad.ag1<<quad.op<<quad.ag2<<endl;
}
char *newtemp()
{
char *p;
char m[12];
p=(char *)malloc(12);
k++;
itoa(k,m,10);
strcpy(p+1,m);
p[0]='t';
return (p);
}
void scaner()
{
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;
}
}
else if((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;
}
else switch(ch)
{
case'<':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
}
else if(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;
}
}
int lrparser()
{//cout<<"调用lrparser"<<endl;
int schain=0;
kk=0;
if(syn==1)
{
scaner();
schain=yucu();
if(syn==6)
{
scaner();
if(syn==0 && (kk==0))
cout<<"success!"<<endl;
}
else
{
if(kk!=1)
cout<<"缺end!"<<endl;
kk=1;
}
}
else
{cout<<"缺begin!"<<endl;kk=1;}
return(schain);
}
int yucu()
{// cout<<"调用yucu"<<endl;
int schain=0;
schain=statement();
while(syn==26)
{
scaner();
schain=statement();
}
return(schain);
}
int statement()
{//cout<<"调用statement"<<endl;
char *eplace,*tt;
eplace=(char *)malloc(12);
tt=(char *)malloc(12);
int schain=0;
switch(syn)
{
case 10:
strcpy(tt,token);
scaner();
if(syn==18)
{
scaner();
strcpy(eplace,expression());
emit(tt,eplace,"","");
schain=0;
}
else
{
cout<<"缺少赋值符!"<<endl;
kk=1;
}
return(schain);
break;
}
return(schain);
}
char *expression(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,"+");
else strcpy(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"<<endl;
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,"*");
else strcpy(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();
}
else if(syn==11)
{
itoa(sum,fplace,10);
scaner();
}
else if(syn==27)
{
scaner();
fplace=expression(); //调用expression分析返回表达式的值
if(syn==28)
scaner();
else
{
cout<<"缺)错误!"<<endl;
kk=1;
}
}
else
{
cout<<"缺(错误!"<<endl;
kk=1;
}
return(fplace);
}
void main()
{
p=0;
cout<<"**********语义分析程序**********"<<endl;
cout<<"Please input string:"<<endl;
do
{
cin.get(ch);
prog[p++]=ch;
}
while(ch!='#');
p=0;
scaner();
lrparser();
}
五、 结果验证
1、给定源程序
begin a:=2+3*4; x:=(a+b)/c end#
输出结果
2、 源程序
begin a:=9; x:=2*3-1; b:=(a+x)/2 end#
输出结果
六、 收获(体会)与建议
通过此次实验,让我了解到如何设计、编制并调试语义分析程序,加深了对语法制导翻译原理的理解,掌握了将语法分析所识别的语法成分变换为中间代码的语义翻译方法。
第二篇:编译原理实验报告模版-语义分析
编译原理课程实验报告
实验3:语义分析