安徽工业大学编译原理实验报告.docx

上传人:b****8 文档编号:9189969 上传时间:2023-05-17 格式:DOCX 页数:30 大小:65.71KB
下载 相关 举报
安徽工业大学编译原理实验报告.docx_第1页
第1页 / 共30页
安徽工业大学编译原理实验报告.docx_第2页
第2页 / 共30页
安徽工业大学编译原理实验报告.docx_第3页
第3页 / 共30页
安徽工业大学编译原理实验报告.docx_第4页
第4页 / 共30页
安徽工业大学编译原理实验报告.docx_第5页
第5页 / 共30页
安徽工业大学编译原理实验报告.docx_第6页
第6页 / 共30页
安徽工业大学编译原理实验报告.docx_第7页
第7页 / 共30页
安徽工业大学编译原理实验报告.docx_第8页
第8页 / 共30页
安徽工业大学编译原理实验报告.docx_第9页
第9页 / 共30页
安徽工业大学编译原理实验报告.docx_第10页
第10页 / 共30页
安徽工业大学编译原理实验报告.docx_第11页
第11页 / 共30页
安徽工业大学编译原理实验报告.docx_第12页
第12页 / 共30页
安徽工业大学编译原理实验报告.docx_第13页
第13页 / 共30页
安徽工业大学编译原理实验报告.docx_第14页
第14页 / 共30页
安徽工业大学编译原理实验报告.docx_第15页
第15页 / 共30页
安徽工业大学编译原理实验报告.docx_第16页
第16页 / 共30页
安徽工业大学编译原理实验报告.docx_第17页
第17页 / 共30页
安徽工业大学编译原理实验报告.docx_第18页
第18页 / 共30页
安徽工业大学编译原理实验报告.docx_第19页
第19页 / 共30页
安徽工业大学编译原理实验报告.docx_第20页
第20页 / 共30页
亲,该文档总共30页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

安徽工业大学编译原理实验报告.docx

《安徽工业大学编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《安徽工业大学编译原理实验报告.docx(30页珍藏版)》请在冰点文库上搜索。

安徽工业大学编译原理实验报告.docx

安徽工业大学编译原理实验报告

安徽工业大学编译原理实验报告

编译原理实验报告

 

姓名:

叶玉虎

班级:

计122班

指导老师:

王森玉

实验日期:

2015/5/11

 

实验内容:

1.求出每个非终结符的FIRST集合

2.求出每个产生式右部的FIRST集合

3.求出每个非终结符的Follow集合

实验环境:

VisualStudio2010

实验目的:

让同学们掌握FIRST集合和FOLLOW集合的求法

实验代码:

#include

#include

#defineMAX50

charcss[MAX][MAX];//保存所有的产生式

intcount=0;

intcnt=0;

structL{//保存所有的终结符

charch;

intflag;//1:

能推出ε,0:

不能,初值:

-1

intnum;

charfirst[MAX];

ints;//first的长度

charfollow[MAX];

intl;//follow的长度

}l[MAX];

//对输入的格式进行控制,并校验输入是否符合格式

inthandle(chara[])

{

intlen,i=0,j,k;

len=strlen(a);

while(a[i]!

=10)

{

if(a[i]=='$')

return2;

if((''==a[i])||(9==a[i]))

{

i++;

continue;

}

if((a[i]>='A')&&(a[i]<='Z'))

{

if((a[i+1]!

='-')||(a[i+2]!

='>'))

{

printf("产生式格式错误\n");

return-1;

}

else

{

j=i;

k=0;

while((a[j]!

='')&&(a[j]!

=9)&&(a[j]!

='$')&&(a[j]!

=10))

{

if(a[j]=='|')

{

css[count][k]='\0';

count++;

if((a[j+1]=='')||(a[j]==9)||(a[j]=='$')||(a[j]==10))

{

printf("产生式格式错误\n");

return0;

}

css[count][0]=a[i];

css[count][1]=a[i+1];

css[count][2]=a[i+2];

k=3;

j++;

continue;

}

css[count][k]=a[j];

k++;

j++;

}

css[count][k]='\0';

i=j;

count++;

}

}

else

{

printf("产生式格式错误\n");

return-1;

}

}

return0;

}

//从键盘获得输入

intinput()

{

chara[MAX*MAX];

intv;

printf("输入产生式,产生式之间以空格回车或Tab键分隔,并以$键结束.\n");

printf("用@表示虚拟符号ε,终结符用大写字母表示,其他字符表示非终结符\n");

while

(1)

{

fgets(a,MAX*MAX,stdin);

v=handle(a);

if(v==-1)

return-1;

if(v==2)

return0;

}

}

//求出能推出ε的非终结符

voidseekEmpty()

{

inti,j,k,t;

intflag=0,flag2=0;

intlen,c;

chara[MAX][MAX],ch;

for(i=0;i

{

strcpy(a[i],css[i]);

}

//求出含有的非终结符的个数,并把各终结符保存起来

for(i=0;i

{

for(j=0;j

{

if(l[j].ch==a[i][0])

{

l[j].num++;

flag=1;

break;

}

else

flag=0;

}

if((!

cnt)||(!

flag))

{

l[cnt].ch=a[i][0];

l[cnt].flag=-1;

l[cnt].num=1;

l[cnt].s=0;

l[cnt].l=0;

cnt++;

flag=1;

continue;

}

}

c=count;

while(c)

{

for(i=0;i

{

//如果该终结符推出ε,从a[]中删除所有带有该终结符的产生式

if(a[i][3]=='@')

{

ch=a[i][0];

for(j=0;j

{

if(ch==a[j][0])

{

if(j!

=c-1)

{

for(k=j;k

strcpy(a[k],a[k+1]);

c--;

j--;

}

else

{

c--;

j--;

}

}

}

for(j=0;j

{

if(ch==l[j].ch)

{

l[j].flag=1;

break;

}

}

i--;

continue;

}

len=strlen(a[i]);

for(j=3;j

{

//当该产生式右边含有非终结符时从a[]中删除该条记录

if((a[i][j]<'A')||(a[i][j]>'Z'))

{

flag2=1;

break;

}

}

if(flag2)

{

for(k=0;k

{

if(a[i][0]==l[k].ch)

{

l[k].num--;

if(l[k].num==0)

l[k].flag=0;

break;

}

}

if(i!

=c-1)

for(k=i;k

{

strcpy(a[k],a[k+1]);

}

c--;

i--;

flag2=0;

continue;

}

//如果产生式右边为非终结符看看该终结符能不能推出ε

for(j=3;j

{

if((a[i][j]>='A')&&(a[i][j]<='Z'))

{

for(k=0;k

{

if(a[i][j]==l[k].ch)

{

if(l[k].flag==0)

{

flag2=1;

break;

}

elseif(l[k].flag==1)

{

for(t=j;t

a[i][t]=a[i][t+1];

a[i][len-1]='\0';

j--;

len--;

break;

}

break;

}

}

if(flag2)

break;

}

}

if(a[i][3]=='\0')

{

ch=a[i][0];

for(j=0;j

{

if(ch==a[j][0])

{

if(j!

=c-1)

{

for(k=j;k

strcpy(a[k],a[k+1]);

c--;

j--;

}

else

{

c--;

j--;

}

}

}

i--;

for(k=0;k

{

if(ch==l[k].ch)

{

l[k].flag=1;

break;

}

}

}

if(flag2)

{

for(k=0;k

{

if(a[i][0]==l[k].ch)

{

l[k].num--;

if(l[k].num==0)

l[k].flag=0;

}

}

if(i!

=c-1)

for(k=i;k

{

strcpy(a[k],a[k+1]);

}

c--;

i--;

flag2=0;

continue;

}

}

}

}

//求每个非终结符的First集合

voidseekFirstVn()

{

inti,j,k,t,t1,t2,c,item;

intlen,s,flag=0,flag2=0,fchange;

chara[MAX][MAX],ch[MAX];

for(i=0;i

{

strcpy(a[i],css[i]);

}

c=count;

while

(1)

{

fchange=0;

for(i=0;i

{

//右部为ε,将ε并入到左部的First中

if(a[i][3]=='@')

{

/*for(j=0;j

{

if(l[j].ch==a[i][0])

{

for(k=0;k

if(l[j].first[k]==a[i][3])

{

flag=1;

break;

}

if(!

flag)

{

l[j].first[l[j].s]=a[i][3];

l[j].s++;

l[j].first[l[j].s]='\0';

fchange=1;

break;

}

flag=0;

}

}*/

//从当前列表a[]中删除

if(i!

=c-1)

for(j=i;j

strcpy(a[j],a[j+1]);

c--;

i--;

continue;

}

len=strlen(a[i]);

//产生式右边符号为终结符时,将该终结符并入到左部的First集合中

for(j=3;j

{

if((a[i][j]<'A')||(a[i][j]>'Z'))

{

for(k=0;k

{

if(a[i][0]==l[k].ch)

{

for(t=0;t

{

if(a[i][j]==l[k].first[t])

{

flag=1;

break;

}

}

if(!

flag)

{

l[k].first[l[k].s]=a[i][j];

l[k].s++;

l[k].first[l[k].s]='\0';

fchange=1;

}

flag=0;

break;

}

}

//从a[][]中删除该条产生式

if(i!

=c-1)

for(k=i;k

strcpy(a[k],a[k+1]);

c--;

i--;

break;

}

//产生式右边符号为非终结符时

elseif((a[i][j]>='A')&&(a[i][j]<='Z'))

{

/*将该非终结符的FIRST集合除去ε并入到当前

非终结符的FIRST集合中*/

for(k=0;k

{

if(a[i][j]==l[k].ch)

{

for(t=0;t

{

if(a[i][0]==l[t].ch)

{

for(t1=0;t1

{

for(t2=0;t2

{

if(l[k].first[t1]==l[t].first[t2])

{

break;

}

}

if((t2==l[t].s)&&(l[k].first[t1])!

='@')

{

fchange=1;

l[t].first[l[t].s]=l[k].first[t1];

l[t].s++;

l[t].first[l[t].s]='\0';

}

}

break;

}

}

break;

}

}

if(l[k].flag)

continue;

else

break;

}

}

}

if(!

fchange)

{

for(i=0;i

{

if(l[i].flag)

{

l[i].first[l[i].s]='@';

l[i].s++;

l[i].first[l[i].s]='\0';

}

printf("FIRST(%c):

%s\n",l[i].ch,l[i].first);

}

printf("\n");

break;

}

}

}

//求产生式右部的First集合

voidseekFirstRight()

{

structRight{

chara[MAX];

charfirst[MAX];

ints;

}r[MAX];

inti,j,k,t;

intcnt=0,len,len1,flag=0;

for(i=0;i

{

for(j=0;j

{

if(!

strcmp(css[i]+3,r[j].a))

{

flag=1;

break;

}

}

if(flag)

{

flag=0;

continue;

}

strcpy(r[j].a,css[i]+3);

r[j].s=0;

cnt++;

}

for(i=0;i

{

len=strlen(r[i].a);

for(j=0;j

{

//遇到终结符

if(r[i].a[j]=='@')

{

r[i].first[r[i].s]='@';

r[i].s++;

r[i].first[r[i].s]='\0';

break;

}

elseif((r[i].a[j]<'A')||(r[i].a[j]>'Z'))

{

r[i].first[r[i].s]=r[i].a[j];

r[i].s++;

r[i].first[r[i].s]='\0';

break;

}

else

{

for(k=0;k

{

if(r[i].a[j]==l[k].ch)

{

len1=strlen(l[k].first);

for(t=0;t

{

if(l[k].first[t]!

='@')

{

r[i].first[r[i].s]=l[k].first[t];

r[i].s++;

r[i].first[r[i].s]='\0';

}

}

break;

}

}

if(l[k].flag)

{

if(j==len-1)

{

r[i].first[r[i].s]='@';

r[i].s++;

r[i].first[r[i].s]='\0';

}

continue;

}

else

break;

}

}

}

for(i=0;i

{

printf("FIRST(%s):

%s\n",r[i].a,r[i].first);

}

printf("\n");

}

//求每个非终极符的Follow集合

voidseekFollow()

{

inti,j,k,t,t1,t2,t3,c=0;

intflag=0,len;

intfchange;//判断一次循环是否有改动的地方

chara[MAX][MAX],ch[MAX];

for(i=0;i

{

len=strlen(css[i]);

for(j=3;j

{

if((css[i][j]>='A')&&(css[i][j]<='Z'))

{

break;

}

}

if(j!

=len)

{

strcpy(a[c],css[i]);

c++;

}

}

l[0].follow[l[0].l]='#';

l[0].l++;

l[0].follow[l[0].l]='\0';

while

(1)

{

fchange=0;

for(i=0;i

{

len=strlen(a[i]);

for(j=3;j

{

if((a[i][j]>='A')&&(a[i][j]<='Z'))

{

//判断该非终结符的前一位是否为非终结符,是的话,

//将其First集合去ε后并到其前一位非终结符的Follow集合中

if((a[i][j-1]>='A')&&(a[i][j-1]<='Z'))

{

for(k=0;k

{

if(a[i][j-1]==l[k].ch)

{

for(t=0;t

{

if(a[i][j]==l[t].ch)

{

for(t1=0;t1

{

if(l[t].first[t1]=='@')

continue;

for(t2=0;t2

if(l[t].first[t1]==l[k].follow[t2])

break;

if(t2==l[k].l)

{

fchange=1;

l[k].follow[l[k].l]=l[t].first[t1];

l[k].l++;

l[k].follow[l[k].l]='\0';

}

}

break;

}

}

break;

}

}

}

//如果该非终结符是最后一位,

//将该产生式左部非终结符的Follow集合

//加入到当前非终结符的Follow集合中.

//然后从当前终结符开始向右判断是否为非终结符,是的话,进行相应处理

//循环直到当前非终结符推不出ε或当

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

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2