实验三 语义分析.docx
- 文档编号:30070103
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:14
- 大小:37.07KB
实验三 语义分析.docx
《实验三 语义分析.docx》由会员分享,可在线阅读,更多相关《实验三 语义分析.docx(14页珍藏版)》请在冰豆网上搜索。
实验三语义分析
实验三语义分析
一、实验目的
通过上机实验,加深对语法制导翻译的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。
二、实验内容
对给定的程序通过语义分析器能够判断语句串是否正确。
正确则输出三地址指令形式的四元式代码,错误则抛出错误信息。
三、实验环境VC++6.0
四、实验步骤方法与关键代码
(1)输入待分析的字符串。
语法如下:
a.关键字:
begin,if,then,while,do,end.
b.运算符和界符:
:
=+-*/<<=>>=<>=;()#
c.其他单词是标识符(ID)和整形常数(NUM):
ID=letter(letter|digit)*,NUM=digitdigit*
d.空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。
(2)扫描字符串,采用递归向下进行分析。
主要函数如下:
a.scaner()//词法分析函数,chartoken[8]用来存放构成单词符号的字符串;
b.parser()//语法分析,在语法分析的基础上插入相应的语义动作:
将输入串翻译成四元式序列。
只对表达式、赋值语句进行翻译。
c.emit(char*result,char*arg1,char*op,char*ag2)//该函数功能是生成一个三地址语句返回四元式表中。
d.char*newtemp()//该函数返回一个新的临时变量名,临时变量名产生的顺序为T1,T2,…。
五、实验分析
对于正确的语句串,运行结果如下:
但是,对于缺少值符号、“end”、”begin”、“(”、“)”等均可做错误判断并给出相应提示,如下图所示:
六源程序实现
#include
#include
#include
charprog[80],token[8];
charch;
intsyn,p,m,n,sum;
intkk=0,ii,N,nn=0;
intk=0,t,i=0;
chartt;
char*keywords[6]={"begin","if","then","while","do","end"};//关键字表。
intscaner();
intparser();
intstatement();
intsentence();
char*term();
char*factor();
char*expression();
voidemit(char*result,char*ag1,char*op,char*ag2);
struct//四元式的结构。
{
charresulted[8];
charag1ed[8];
charoped[8];
charag2ed[8];
}quad[20];
voidmain()
{
p=0;
printf("请输入字符串,以#号结束:
\n");
do
{
scanf("%c",&ch);
prog[p++]=ch;
}while(ch!
='#');//没有遇到结束符,则首先调用scaner()进行词法分析,之后进行语义分析。
p=0;
scaner();
parser();
}
char*newtemp(void)//返回一个新的临时变量名,临时变量名产生的顺序为t1,t2,…。
{
char*P;
charM[8];
P=(char*)malloc(8);
k++;
itoa(k,M,10);
strcpy(P+1,M);
P[0]='t';
return(P);
}
intparser()//在语法分析的基础上插入相应的语义动作:
将输入串翻译成四元式序列。
只对表达式、赋值语句进行翻译。
{
intschain=0;
kk=0;
if(syn==1)
{
scaner();
schain=sentence();//调用语句串分析函数进行分析。
if(syn=6)//"end"。
{
scaner();
if(syn==0&&(kk==0))
printf("success");
}
else
{
if(kk!
=1)
printf("缺end错误");//输出"end"错误。
kk=1;
}
}
else
{
printf("begin错误");//输出"begin"错误。
kk=1;
}
return(schain);
}
intsentence()//语句串分析函数。
{
intschain=0;
schain=statement();//调用语句分析函数进行分析。
while(syn==26)//";"。
{
scaner();
schain=statement();//调用语句分析函数进行分析。
}
return(schain);
}
intstatement()//语句分析函数。
{
chartt[8],eplace[8];
intschain=0;
switch(syn)
{
case10:
strcpy(tt,token);
scaner();
if(syn==18)//赋值语句。
{
scaner();
strcpy(eplace,expression());
emit(tt,eplace,"","");
schain=0;
}
else
{
printf("缺少赋值号");//缺少":
="错误。
kk=1;
}
return(schain);
break;
}
}
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==13||syn==14)//加减。
{
strcpy(tt,token);
scaner();
strcpy(ep2,term());//调用term()分析产生表达式计算的第二项ep2。
strcpy(tp,newtemp());//调用newtemp()产生临时变量tp存储计算结果。
emit(tp,eplace,tt,ep2);//生成四元式送入四元式表。
strcpy(eplace,tp);
}
return(eplace);
}
char*term(void)
{
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==15||syn==16)//乘除。
{
strcpy(tt,token);
scaner();
strcpy(ep2,factor());
strcpy(tp,newtemp());
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);
scaner();
}
elseif(syn==11)//数字。
{
itoa(sum,fplace,10);
scaner();
}
elseif(syn==27)//"("。
{
scaner();
strcpy(fplace,expression());
if(syn==28)//有")"。
scaner();
else
{
printf("')'错误");//只有"(",缺少")"。
kk=1;
}
}
else
{
printf("'('错误");
kk=1;
}
return(fplace);
}
voidemit(char*result,char*ag1,char*op,char*ag2)//生成一个三地址码并返回到四元式代码中。
{
strcpy(quad[nn].resulted,result);
strcpy(quad[nn].ag1ed,ag1);
strcpy(quad[nn].oped,op);
strcpy(quad[nn].ag2ed,ag2);
printf("(%d)%s=%s%s%s\n",nn+1,quad[nn].resulted,quad[nn].ag1ed,quad[nn].oped,quad[nn].ag2ed);
nn++;
}
scaner()//此函数为词法分析。
{
for(n=0;n<8;n++)token[n]=NULL;
ch=prog[p++];m=0;
while(ch=='')ch=prog[p++];
if((ch>='a')&&(ch<='z'))//判断是否是字母。
{
while((ch>='a')&&(ch<='z')||(ch>='0')&&(ch<='9'))//判断下一个是否是字母或数字。
{
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
p--;
syn=10;
for(n=0;n<6;n++)
if(strcmp(token,keywords[n])==0)//判断是否匹配关键字。
{
syn=n+1;
break;
}
}
elseif(ch>='0'&&ch<='9')//判断数字。
{
sum=0;
while((ch>='0')&&(ch<='9'))//判断下一个是否是数字。
{
sum=sum*10+(int)ch-'0';
ch=prog[p++];
}
p--;
syn=11;
}
else
switch(ch)
{
case'<':
//是否是"<"。
m=0;
token[m++]=ch;
if(ch=='>')//是否是">"。
{
syn=21;
token[m++]=ch;
}elseif(ch=='=')//判断下一个是否是"=",即为判断符号"<="。
{
syn=22;
token[m++]=ch;
}
else
{
syn=20;
ch=prog[p++];
}
break;
case'>':
//是否是">"。
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='=')//判断下一个是否是"=",即为判断符号">="。
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
p--;
break;
}
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;
}
returnsyn;
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验三 语义分析 实验 语义 分析
![提示](https://static.bdocx.com/images/bang_tan.gif)