编译原理实验算符优先分析Word格式.docx
《编译原理实验算符优先分析Word格式.docx》由会员分享,可在线阅读,更多相关《编译原理实验算符优先分析Word格式.docx(18页珍藏版)》请在冰点文库上搜索。
![编译原理实验算符优先分析Word格式.docx](https://file1.bingdoc.com/fileroot1/2023-5/6/f8a1d1bc-3b2c-4c83-a6bc-3e3ffc816b2d/f8a1d1bc-3b2c-4c83-a6bc-3e3ffc816b2d1.gif)
inti,j;
intflag=0;
for(i=0;
i<
length;
i++)
{
for(j=0;
j<
strlen(G[i].Right)-1;
j++)
if(Capital(G[i].Right[j])==1&
Capital(G[i].Right[j+1])==1)
{
flag=1;
break;
}
}
if(flag==1)
cout<
<
"
该文法不是算符文法!
endl;
return;
该文法是算符文法!
voidClean(dbVNT[],intlength1)//去掉集合中重复部分
charstr1[20];
charstr2[20][100];
inti,j,k,t;
intlength;
intflag;
length1;
str1[i]=VNT[i].VN;
strcpy(str2[i],VNT[i].VtoT);
memset(VNT[i].VtoT,0,sizeof(VNT[i].VtoT));
t=0;
length=strlen(str2[i]);
{
flag=1;
for(k=0;
k<
t;
k++)
if(VNT[i].VtoT[k]==str2[i][j])
flag=0;
if(flag==1)
VNT[i].VtoT[t++]=str2[i][j];
}
length=strlen(VNT[i].VtoT);
voidFIRSTVT(cscG[],dbfirstvt[],intlength)//求各非终结符的FIRSTVT集合
intflag=0,length1=0;
inti,j,k;
100;
memset(firstvt[i].VtoT,0,sizeof(firstvt[i].VtoT));
while(flag<
length)
j=0;
firstvt[length1].VN=G[flag].Left;
while(firstvt[length1].VN==G[flag].Left)
if(Capital(G[flag].Right[0])==0)//P->
a...则将a加入firstvt(P)中
firstvt[length1].VtoT[j++]=G[flag].Right[0];
elseif(Capital(G[flag].Right[0])==1&
Capital(G[flag].Right[1])==0)//P->
Qa...则将a加入firstvt(P)中
firstvt[length1].VtoT[j++]=G[flag].Right[1];
flag++;
length1++;
for(i=length-1;
i>
=0;
i--)//P->
Q...,则将Q中的终结符加入P中
if(Capital(G[i].Right[0])==1&
G[i].Left!
=G[i].Right[0])
for(j=0;
if(firstvt[j].VN==G[i].Right[0])
break;
if(firstvt[k].VN==G[i].Left)
strcat(firstvt[k].VtoT,firstvt[j].VtoT);
Clean(firstvt,length1);
i++)//集合输出
FIRSTVT("
;
firstvt[i].VN<
)"
="
{"
firstvt[i].VtoT[0];
for(j=1;
strlen(firstvt[i].VtoT);
cout<
"
firstvt[i].VtoT[j];
}"
voidLASTVT(cscG[],dblastvt[],intlength)//求各非终结符的FIRSTVT集合
memset(lastvt[i].VtoT,0,sizeof(lastvt[i].VtoT));
lastvt[length1].VN=G[flag].Left;
while(lastvt[length1].VN==G[flag].Left)
t=strlen(G[flag].Right)-1;
if(Capital(G[flag].Right[t])==0)//P->
...a则将a加入lastvt(P)中
lastvt[length1].VtoT[j++]=G[flag].Right[t];
elseif(Capital(G[flag].Right[t])==1&
Capital(G[flag].Right[t-1])==0)//P->
...aQ则将a加入lastvt(P)中
lastvt[length1].VtoT[j++]=G[flag].Right[t-1];
...Q,则将Q中的终结符加入P中
t=strlen(G[flag].Right)-1;
if(Capital(G[i].Right[t])==1&
=G[i].Right[t])
if(lastvt[j].VN==G[i].Right[t])
if(lastvt[k].VN==G[i].Left)
strcat(lastvt[k].VtoT,lastvt[j].VtoT);
Clean(lastvt,length1);
LASTVT("
lastvt[i].VN<
lastvt[i].VtoT[0];
strlen(lastvt[i].VtoT);
lastvt[i].VtoT[j];
voidStructureTable(cscG[],dbfirstvt[],dblastvt[],intlength)//返回非终结符个数
charstr[50];
//存放终结符
inti,j,k,flag,i1,i2,length1;
intt=0;
50;
memset(str1[i],0,sizeof(str1[i]));
memset(str,0,sizeof(str));
i++)//求所有非终结符
{
j=strlen(G[i].Right);
flag=1;
for(k=0;
j;
if(Capital(G[i].Right[k])==0)
for(i1=0;
i1<
i1++)
if(G[i].Right[k]==str[i1])
flag=0;
if(flag==1)
str[t++]=G[i].Right[k];
strlen(str);
i++)//与习惯保持一致,将#置于最后一个
if(str[i]=='
#'
break;
swap(str[i],str[strlen(str)-1]);
for(i=1;
=strlen(str);
str1[0][i]=str[i-1];
str1[i][0]=str[i-1];
length1=strlen(G[i].Right);
length1-1;
if(Capital(G[i].Right[j])==0&
Capital(G[i].Right[j+1])==0)
for(i2=0;
i2<
i2++)
if(str1[0][i1]==G[i].Right[j]&
str1[i2][0]==G[i].Right[j+1])
{
if(str1[i1][i2]!
=0)
{
cout<
该文法不是算符优先文法!
return;
}
else
str1[i1][i2]='
}
if(j<
length1-2&
Capital(G[i].Right[j])==0&
Capital(G[i].Right[j+2])==0&
str1[i2][0]==G[i].Right[j+2])
return;
str1[0][i1]!
=G[i].Right[j];
i1++);
for(k=0;
firstvt[k].VN!
=G[i].Right[j+1];
k++);
for(i2=0;
for(t=0;
t<
strlen(firstvt[k].VtoT);
t++)
if(str1[i2][0]==firstvt[k].VtoT[t])
'
for(t=0;
lastvt[t].VN!
t++);
strlen(lastvt[t].VtoT);
for(i1=0;
for(i2=0;
if(str1[0][i1]==lastvt[t].VtoT[k]&
if(str1[i1][i2]!
{
cout<
return;
}
else
str1[i1][i2]='
>
str1[i][j]<
"
charGetRalation(chara,charb)//找到a,b对应的关系
str1[0][i]!
=a;
i++);
for(j=0;
str1[j][0]!
=b;
j++);
returnstr1[i][j];
voidJudge(char*str,cscG[])
charQ;
chara;
charstr2[100];
charS[100];
inti=0;
intj,k;
ints=0,step=1;
cout.width(5);
//输出表头
cout.setf(ios:
:
left);
cout<
步骤"
cout.width(15);
符号栈"
输入串"
动作"
memset(S,0,sizeof(S));
a=str[0];
k=1;
S[k]='
while(a!
a=str[flag++];
if(Capital(S[k])==0)
j=k;
else
j=k-1;
while(GetRalation(S[j],a)=='
Q=S[j];
while(GetRalation(S[j],Q)!
Q=S[j];
if(Capital(S[j-1])==0)
j=j-1;
else
j=j-2;
}
cout.width(5);
cout.setf(ios:
step++;
cout.width(15);
S+1;
str+flag-1;
规约"
for(i=j+2;
=k;
S[i]=0;
k=j+1;
S[k]='
N'
if(GetRalation(S[j],a)=='
||GetRalation(S[j],a)=='
//cout.setf(ios:
right);
if(a!
cout.width(15);
cout.setf(ios:
cout<
移进"
k=k+1;
S[k]=a;
抱歉,输入的句子有误"
return;
接受"
恭喜你!
分析成功!
voidmain()
charstr3[100];
//用于存放一个产生式子
//用于存放待检测的字符串
charfilename[10];
//文件名
intlength=0;
//记录产生式个数
ints=0;
请输入文件名:
cin>
filename;
memset(str1,0,sizeof(str1));
//置空字符串
ifstreamfin1(filename);
if(!
fin1)
Cannotopenthefile.\n"
//未找到对应文件名的文件
exit
(1);
}
while(fin1)
fin1.getline(str3,100);
//读出一个产生式
str3<
G[length].Left=str3[0];
//产生式的左部
strcpy(G[length].Right,str3+3);
length++;
length-=1;
Issfwf(G,length);
各非终结符的FIRSTVT集合如下:
FIRSTVT(G,firstvt,length);
各非终结符的LASTVT集合如下:
LASTVT(G,lastvt,length);
构造分析表如下:
StructureTable(G,firstvt,lastvt,length);
请任意输入一个输入串(以#号键结束):
str2;
Judge(str2,G);
调试文件内容:
Z->
#E#
E->
E+T
T
T->
T*F
F
F->
P^F
P
P->
(E)
i
结果截图: