编译原理实验报告Word格式.docx
- 文档编号:20372297
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:30
- 大小:78.55KB
编译原理实验报告Word格式.docx
《编译原理实验报告Word格式.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告Word格式.docx(30页珍藏版)》请在冰豆网上搜索。
若x为终结符,则x的first集合为x
若x为非终结符,切有产生式x->
a....,a为非终结符,则x的first集合一定包含有a
若x为非终结符,切x能够推出空,则x对应的first集合一点包含有空
若x,y1,y2,y3,...,yn,其中已知x,y1为非终结符,遍历右部,找到第一个不能够推出空的数组,将其前面的所有的集合的first集合去掉空以后加到x的first集合里面
反复执行~④,直到first集合没有在发生增大为止
3、求解follow集合
设置s为文法的开始符号,把{#}加入到s的follow集合里面
若A->
αBβ,是一个产生式,则把first[β]集合的添加到B的follow集合里面,若β可以退出空,则将A的follow集合添加到B的follow集合里面
反复使用步骤二,直到每个非终结符的follow集合不在增加为止
4、求解select集合
对于给定的上下文无关文法的产生式A->
α,A为非终结符,α为一串符号串
若α可以推出空,则select(A->
α)=first(α);
若α不能够推出空,则select(A->
a)=(first(α)-{*})并上follow(A),其中*表示空
5、实验代码:
#include<
iostream>
string>
#defineN100
usingnamespacestd;
//s1、s2视为集合(该集合如果包含'
*'
,则一定在集合最后),此方法返回集合的并集且如果包含'
,一定在最后
//使用此函数后若比较返回值是否与s1相等,则请将s1做为第一个参数传入
stringAddArray(strings1,strings2)
{
bools1Have=0;
stringresult;
if(s1[s1.length()-1]=='
)
{
result=string(s1,0,s1.length()-1);
s1Have=1;
}
else
result=s1;
for(inti=0;
i<
s2.length();
i++)
for(intj=0;
j<
s1.length();
j++)
{
if(s2[i]==s1[j])
{
break;
}
}
if(j==s1.length())
result=result+string(1,s2[i]);
if(s1Have)
result=result+"
*"
;
returnresult;
}
//s1是集合(若含有'
,只能是在最后),此方法返回s1集合去掉'
后的集合
stringSubNull(strings1)
if(s1.length()==0)
returns1;
elseif(s1[s1.length()-1]=='
s1=string(s1,0,s1.length()-1);
returns1;
//将文法的产生式输入到数组中
intGrammarGet(charleft[],stringright[],stringtempright[],stringselect[][N])
inti=0;
stringtemp;
while
(1)
getline(cin,temp);
if(temp!
="
#"
select[0][i]=temp;
left[i]=temp[0];
right[i]=temp.substr(3,temp.length()-3);
tempright[i]=right[i];
i++;
else
returni;
//找出各个非终结符存储到数组,并初始化每个非终结符未定
intFindVn(charleft[],chartag[][N/2],intv_amount)
intvn_amount=0;
v_amount;
vn_amount;
if(tag[0][j]!
=left[i])
continue;
else
if(j==vn_amount)
tag[0][j]=left[i];
tag[1][j]='
0'
vn_amount++;
returnvn_amount;
//该方法对应于P80算法中的第
(2)步
voidRelating2nd(charleft[],stringright[],chartag[][N/2],intv_amount,intvn_amount)
boolrelating21=1;
right[i].length();
if((right[i][j]<
'
A'
||right[i][j]>
Z'
)&
&
right[i][j]!
='
right[i]="
EOF"
for(i=0;
if(left[j]==tag[0][i]&
right[j]!
relating21=0;
if(relating21)
tag[1][i]='
1'
//1不能推出空
relating21=1;
if(right[i]=="
for(intj=0;
if(left[j]==left[i])
{
right[i]="
}
for(j=0;
if(tag[0][j]==left[i])
tag[1][j]='
//0能推出空
break;
//该方法对应于P80算法中的第(3)步
voidRelating3rd(charleft[],stringright[],chartag[][N/2],intv_amount,intvn_amount)
inttagt;
do
tagt=0;
if(right[j]=="
for(inti=0;
right[j].length();
if(right[j][i]>
&
right[j][i]<
for(intk=0;
k<
k++)
{
if(tag[0][k]==right[j][i])
break;
}
if(tag[1][k]=='
if(i==right[j].length()-1)
{
right[j]=string(right[j],0,i);
i--;
}
else
right[j]=string(right[j],0,i)+string(right[j],i+1,right[j].length()-i-1);
if(right[j].length()==0)
for(intp=0;
p<
p++)
{
if(tag[0][p]==left[j])
{
tag[1][p]='
tagt++;
}
}
for(p=0;
if(right[p]=="
continue;
if(left[p]==left[j])
right[p]="
elseif(tag[1][k]=='
right[j]="
for(intp=0;
if(right[p]=="
continue;
while(left[p]!
=left[j])
if(p==v_amount)
break;
}while(tagt!
=0);
//计算first集
voidFirstComputer(charleft[],stringright[],chartag[][N/2],stringfirst[][N/2],intv_amount,intvn_amount)
boolrightAllVn;
intfirstNoNull;
intfirstNoNullTemp;
stringchangeCheck;
//检测First集合是否还在增大
for(inti=0;
firstNoNull=0;
//标志量的位置不能设错
firstNoNullTemp=0;
//这三个标志量分别表示该行第一个不能推出空的位置、该行右部都是非终结符
rightAllVn=1;
if(left[j]==first[0][i][0])//对每个非终结符X检查以其为左部的产生式
if((right[j][0]<
||right[j][0]>
right[j][0]!
)//X->
a...,a∈Vt
changeCheck=first[1][i];
first[1][i]=AddArray(first[1][i],string(1,right[j][0]));
//a加入FIRST(X)
if(changeCheck!
=first[1][i])
tagt++;
continue;
elseif(right[j]=="
)//X->
*
first[1][i]=AddArray(first[1][i],right[j]);
//*加入FIRST(X)
/*for(intk=0;
k++)
if(right[j][k]<
||right[j][k]>
rightAllVn=0;
//对X推出的产生式右部只要有一个不是非终结符,rightAllVn=0
*/
if(((right[j][0]<
)||right[j][0]=='
rightAllVn=0;
if(rightAllVn)//此产生式右部第一个是非终结符
for(intk=0;
if((right[j][k]<
right[j][k]!
firstNoNull=k;
break;
if(tag[0][p]==right[j][k])
if(tag[1][p]=='
2'
{
firstNoNull++;
//记录此产生式右部第一个不能推出空的非终结符位置
}
if(firstNoNullTemp==firstNoNull)//如果第一个不能推出空的非终结符位置不变了,则找到了
else
firstNoNullTemp=firstNoNull;
if(firstNoNull!
=right[j].length())//不是所有终结符都推出空
for(k=0;
firstNoNull;
k++)//对推出空的循环
for(intp=0;
if(first[0][p][0]==right[j][k])
temp=SubNull(first[1][p]);
//FIRST(Yi-1)-{*},此操作不应该改变FIRST(Yi-1)
changeCheck=first[1][i];
first[1][i]=AddArray(first[1][i],temp);
//FIRST(X)加入(FIRST(Yi-1)-{*})
if(changeCheck!
tagt++;
break;
if((right[j][firstNoNull]<
||right[j][firstNoNull]>
right[j][firstNoNull]!
changeCheck=first[1][i];
first[1][i]=AddArray(first[1][i],string(1,right[j][firstNoNull]));
if(changeCheck!
p++)
if(first[0][p][0]==right[j][firstNoNull])
first[1][i]=AddArray(first[1][i],first[1][p]);
//FIRST(X)加入FIRST(Yi)
tagt++;
else//所有终结符都推出空
for(intk=0;
//FIRST(X)中加入FIRST(Yn)
changeCheck=first[1][i];
first[1][i]=AddArray(first[1][i],"
);
if(changeCheck!
tagt++;
//计算follow集
voidFollowComputer(charleft[],stringright[],constchartag[][N/2],conststringfirst[][N/2],stringfollow[][N/2],intv_amount,intvn_amount)
stringbeginSignal;
cout<
<
"
Inputthebeginsignalofthegrammar:
cin>
>
beginSignal;
stringtempt;
if(follow[0][i]==beginSignal)
follow[1][i]=AddArray(follow[1][i],"
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 报告