实验三 自下而上语法分析及语义分析.docx

上传人:b****8 文档编号:9708993 上传时间:2023-02-06 格式:DOCX 页数:13 大小:31.95KB
下载 相关 举报
实验三 自下而上语法分析及语义分析.docx_第1页
第1页 / 共13页
实验三 自下而上语法分析及语义分析.docx_第2页
第2页 / 共13页
实验三 自下而上语法分析及语义分析.docx_第3页
第3页 / 共13页
实验三 自下而上语法分析及语义分析.docx_第4页
第4页 / 共13页
实验三 自下而上语法分析及语义分析.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

实验三 自下而上语法分析及语义分析.docx

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

实验三 自下而上语法分析及语义分析.docx

实验三自下而上语法分析及语义分析

实验三自下而上语法分析及语义分析

一、实验目的:

通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。

二、实验学时:

4学时。

三、实验内容

根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。

对于正确的表达式,给出表达式的值。

对于错误的表达式,给出出错位置。

四、实验方法

采用LR分析法。

首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。

属性文法的定义可参照书137页表6.1),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表6.5)。

接下来给出LR分析表。

然后程序的具体实现:

●LR分析表可用二维数组(或其他)实现。

●添加一个val栈作为语义分析实现的工具。

●编写总控程序,实现语法分析和语义分析的过程。

注:

对于整数的识别可以借助实验1。

五、文法定义

简单的表达式文法如下:

E->E+T|E-T|T

T->T*F|T/F|F

F->(E)|i

上式中,i为整数。

六、处理程序例

例1:

正确源程序例:

23+(45+4)*40分析结果应为:

正确的表达式。

其值为:

1983

例2:

错误源程序例:

5+(56+)-24

分析结果应为:

错误的表达式:

出错位置为)

附录:

源程序

#include

#include"string.h"

#include

usingnamespacestd;

#defineR30

#defineC20

typedefstructelem

{

chare[4];

}Elem;//ACTION表与GoTo表中的元素类型

ElemLR[R][C];//存放ACTION表与GoTo表中的内容

typedefstructout

{

intorder;//序号

intstate[10];//状态栈

charsign[30];//符号栈

chargrasen[20];//产生式

charinput[30];//输入串

charexplen[50];//解释说明

}OutNode;//输出结果中每一行的类型

OutNodeout[20];//存放输出结果

charSentence[20];//存放文法的一个句子

charGramSent[10][20];//存放文法的一组产生式

introw,colno;//row为状态个数数,colno为ACTION表与GoTo表列总数

intstateTop=0,signTop=0;//状态栈与符号栈的栈顶位置(值与栈中元素的个数相等)

voidinput_GramSent()

{

inti,num;

printf("请输入文法中产生式的个数\n");

scanf("%d",&num);

for(i=0;i

{

printf("请输入文法的第%d个产生式\n",i);

scanf("%s",GramSent+i-1);

}

printf("请输入文法的一个句子\n");

scanf("%s",Sentence);

printf("**********************************************************\n");

printf("*文法的产生式如下:

*\n");

printf("**********************************************************\n");

for(i=0;i

printf("%s\n",GramSent+i);

printf("**********************************************************\n");

printf("*文法的句子如下:

*\n");

printf("**********************************************************\n");

printf("%s\n",Sentence);

}

voidinput_LR(introw,intcolno)//row为行总数,colno为列总数

{

inti,j;

charmid[4];

printf("**********************************************************\n");

printf("*提示:

每输入一个元素后就回车*\n");

printf("**********************************************************\n");

printf("请输入LR分析表的终结符(包括#)与非终结符\n");

for(j=0;j

scanf("%s",LR[0][j].e);

for(i=0;i

{

printf("请输入%d号状态所对应的各列的元素,空白的地方用s代替\n",i);

for(j=0;j

{

scanf("%s",mid);

if(strcmp(mid,"s")==0||strcmp(mid,"S")==0)

strcpy(LR[i+1][j].e,"");

else

strcpy(LR[i+1][j].e,mid);

}

}

}

voidoutput_LR(introw,intcolno)

{

inti,j;

printf("**********************************************************\n");

printf("*LR分析表如下:

*\n");

printf("**********************************************************\n");

printf("\n");

printf("");

for(j=0;j

printf("%s",LR[0][j].e);

printf("\n");

for(i=1;i<=row;i++)

{

printf("%d",i-1);

for(j=0;j

printf("%s",LR[i][j].e);

printf("\n");

}

printf("\n");

}

intSignNum(charch)//给定一个终结符或非终结符,返回其在ACTION表与GoTo表中的列位置

{

inti;

charc[2]="0";

c[0]=ch;

for(i=0;i

if(strcmp(c,LR[0][i].e)==0)

returni;

return-1;

}

intCharChangeNum(char*ch)//给定一数字字符串,返回其所对应的数字

{

intresult=0;

while(*ch!

='\0')

{

result=result*10+(*ch-'0');

ch++;

}

returnresult;

}

intOutResult(ints,intc,inti)//输出结果的第i+1行处理函数,(s为状态,c为列)

{

charmid[4],gra[20];

ints_num,r_num;

intn,len,j;

strcpy(mid,LR[s+1][c].e);

if(strcmp(mid,"")==0)

{printf("不能规约\n");return-2;}

if(strcmp(mid,"acc")==0||strcmp(mid,"ACC")==0)

{printf("规约成功\n");return-1;}

out[i+1].order=i+2;

if(mid[0]=='s'||mid[0]=='S')

{

s_num=CharChangeNum(mid+1);//s_num为S后的数字

for(j=0;j

out[i+1].state[j]=out[i].state[j];

out[i+1].state[stateTop]=s_num;

out[i+1].state[++stateTop]=-1;//完成第i+1行的状态栈赋值

strcpy(out[i+1].sign,out[i].sign);

out[i+1].sign[signTop]=out[i].input[0];

out[i+1].sign[++signTop]='\0';//完成第i+1行的符号栈的赋值

strcpy(out[i+1].grasen,"");//完成第i+1行的产生式的赋值

strcpy(out[i+1].input,out[i].input+1);//完成第i+1行的输入符号串的赋值

}

elseif(mid[0]=='r'||mid[0]=='R')

{

r_num=CharChangeNum(mid+1);//r_num为r后的数字

strcpy(gra,*(GramSent+r_num-1));

len=strlen(gra);

for(j=0;j

if(gra[j]=='-'&&gra[j+1]=='>')

break;

n=strlen(gra+j+2);

stateTop-=n;signTop-=n;

for(j=0;j

out[i+1].state[j]=out[i].state[j];

j=SignNum(gra[0]);

out[i+1].state[stateTop]=CharChangeNum(LR[out[i+1].state[stateTop-1]+1][j].e);

out[i+1].state[++stateTop]=-1;//完成第i+1行的状态栈赋值

strcpy(out[i+1].sign,out[i].sign);

out[i+1].sign[signTop]=gra[0];

out[i+1].sign[++signTop]='\0';//完成第i+1行的符号栈的赋值

strcpy(out[i+1].grasen,gra);//完成第i+1行的产生式的赋值

strcpy(out[i+1].input,out[i].input);//完成第i+1行的输入符号串的赋值

}

return1;

}

voidOutputResult(intr)

{

inti,j;

printf("**********************************************************\n");

printf("*句子:

%s用LR分析表规约过程如下:

*\n",Sentence);

printf("**********************************************************\n");

for(i=0;i<=r;i++)

{

j=0;

printf("%2d",out[i].order);

while(out[i].state[j]!

=-1)

printf("%d",out[i].state[j++]);

printf("%s%s%s\n",out[i].sign,out[i].grasen,out[i].input);

}

}

intOutControl()//输出结果的总控函数

{

ints_num,i=0;

out[0].order=1;//序号赋值

out[0].state[0]=0;stateTop=1;out[0].state[stateTop]=-1;//状态栈赋值,置栈顶位

strcpy(out[0].sign,"#");signTop=1;//符号栈赋值,置栈顶位

strcpy(out[0].grasen,"");//产生式为空

strcpy(out[0].input,Sentence);//以下两行为输入串赋值

strcat(out[0].input,"#");

strcpy(out[0].explen,"0和#进栈");//解释说明

//初使化输出结果的第一行

while

(1)

{

s_num=SignNum(out[i].input[0]);

//if(s_num!

=-1)

if(OutResult(out[i].state[stateTop-1],s_num,i)!

=1)

break;

i++;

}

returni;

}

main()

{

intr;

printf("**********************************************************\n");

printf("*函数的输入:

文法的产生式,文法句型的一个句子,LR分析表*\n");

printf("*函数的输出:

LR分析器的工作过程与说明*\n");

printf("**********************************************************\n");

printf("请输入LR分析表中终结符与非终结符的总个数\n");

scanf("%d",&colno);

printf("请输入LR分析表中状态的总个数\n");

scanf("%d",&row);

input_LR(row,colno);

output_LR(row,colno);

input_GramSent();

r=OutControl();//r为输出结果的行数

OutputResult(r);

}

七、实验小结

这个程序是从网上下载下来的,根据这个实验要求做了些更改,但是总是出现溢出错误,只能运行到LR分析表的部分(如截图),没有找到解决问题的办法。

(注:

专业文档是经验性极强的领域,无法思考和涵盖全面,素材和资料部分来自网络,供参考。

可复制、编制,期待你的好评与关注)

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

当前位置:首页 > 总结汇报 > 学习总结

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

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