实验三 语义分析.docx

上传人:b****5 文档编号:30070103 上传时间:2023-08-04 格式:DOCX 页数:14 大小:37.07KB
下载 相关 举报
实验三 语义分析.docx_第1页
第1页 / 共14页
实验三 语义分析.docx_第2页
第2页 / 共14页
实验三 语义分析.docx_第3页
第3页 / 共14页
实验三 语义分析.docx_第4页
第4页 / 共14页
实验三 语义分析.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

实验三 语义分析.docx

《实验三 语义分析.docx》由会员分享,可在线阅读,更多相关《实验三 语义分析.docx(14页珍藏版)》请在冰豆网上搜索。

实验三 语义分析.docx

实验三语义分析

实验三语义分析

一、实验目的

通过上机实验,加深对语法制导翻译的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。

二、实验内容

对给定的程序通过语义分析器能够判断语句串是否正确。

正确则输出三地址指令形式的四元式代码,错误则抛出错误信息。

三、实验环境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;

}

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 小学作文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1