编译原理实验报告.docx

上传人:b****5 文档编号:7265158 上传时间:2023-01-22 格式:DOCX 页数:30 大小:78.55KB
下载 相关 举报
编译原理实验报告.docx_第1页
第1页 / 共30页
编译原理实验报告.docx_第2页
第2页 / 共30页
编译原理实验报告.docx_第3页
第3页 / 共30页
编译原理实验报告.docx_第4页
第4页 / 共30页
编译原理实验报告.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

编译原理实验报告.docx

《编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告.docx(30页珍藏版)》请在冰豆网上搜索。

编译原理实验报告.docx

编译原理实验报告

编译原理实验报告

 

 

学号:

姓名:

班级:

指导教师:

时间:

 

实验题目:

LL

(1)文法的判别

1、求解能够推出空的终结符

1):

实验思想

:

将输入的文法分为左部和右部,左部用一个一维的char数组存储,右部用二维的String数组存储,通过两个数组接收输入的文法的中‘->’符号左右两边的数据,由于java中没有结构体,于是乎用一个类来实现结构体的功能,首先创建该类的一个对象数组,每一个数组中有通过调用相应的该类中的私有变量来实现相当于结构体重的数据功能,改类中有是有变量:

左部:

charleft右部:

String[]right标志位:

intstandard;,可以通过get和set方法修改相应的值和获取相应的值,

删除右部所有含有终结符的产生式,若这使得某一个非终结符为左部的所有产生式都被删除了,则将对象数组中该非终结符对应的标志位改为否(用0表示),说明该非终结符不能够推出空

若某一非终结符的某一产生式的右部对应的空,则将对象数组中对应的给非终结符的标志位改为是(用1表示),并从文法中删除所有产生式

④:

若扫描到的非终结符对应的标志位为否,则删除改产生式,若这使得该非终结符对应的产生式的右部为空,则对应的左部的非终结符对应的标志位为是,并删除该非终结符对应的所有右部

⑤:

若扫描到的非终结符对应的标志位为否,则删去改产生式,若这使得产生式的左部非终结符的有关产生式都被删去,则把非终结符对应的特征值改为否

⑥:

重复④⑤,直到对象数组中的非终结符对应的特征值不会再发生改变为止

2、求解first集合

1):

实验思想

:

若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集合

1):

实验思想

:

设置s为文法的开始符号,把{#}加入到s的follow集合里面

若A->αBβ,是一个产生式,则把first[β]集合的添加到B的follow集合里面,若β可以退出空,则将A的follow集合添加到B的follow集合里面

反复使用步骤二,直到每个非终结符的follow集合不在增加为止

4、求解select集合

1):

实验思想

:

对于给定的上下文无关文法的产生式A->α,A为非终结符,α为一串符号串

若α可以推出空,则select(A->α)=first(α);

若α不能够推出空,则select(A->a)=(first(α)-{*})并上follow(A),其中*表示空

5、实验代码:

#include

#include

#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

{

for(intj=0;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;

for(inti=0;i

{

for(intj=0;j

{

if(tag[0][j]!

=left[i])

continue;

else

break;

}

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;

for(inti=0;i

{

for(intj=0;j

{

if((right[i][j]<'A'||right[i][j]>'Z')&&right[i][j]!

='*')

{

right[i]="EOF";

break;

}

}

}

for(i=0;i

{

for(intj=0;j

{

if(left[j]==tag[0][i]&&right[j]!

="EOF")

relating21=0;

}

if(relating21)

{

tag[1][i]='1';//1不能推出空

}

relating21=1;

}

for(i=0;i

{

if(right[i]=="*")

{

for(intj=0;j

{

if(left[j]==left[i])

{

right[i]="EOF";

}

}

for(j=0;j

{

if(tag[0][j]==left[i])

{

tag[1][j]='0';//0能推出空

break;

}

}

}

}

}

//该方法对应于P80算法中的第(3)步

voidRelating3rd(charleft[],stringright[],chartag[][N/2],intv_amount,intvn_amount)

{

inttagt;

do

{

tagt=0;

for(intj=0;j

{

if(right[j]=="EOF")

continue;

for(inti=0;i

{

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

{

for(intk=0;k

{

if(tag[0][k]==right[j][i])

break;

}

if(tag[1][k]=='0')

{

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);

i--;

}

if(right[j].length()==0)

{

for(intp=0;p

{

if(tag[0][p]==left[j])

{

tag[1][p]='0';

tagt++;

}

}

for(p=0;p

{

if(right[p]=="EOF")

continue;

if(left[p]==left[j])

{

right[p]="EOF";

}

}

}

}

elseif(tag[1][k]=='1')

{

right[j]="EOF";

for(intp=0;p

{

if(right[p]=="EOF")

continue;

while(left[p]!

=left[j])

{

continue;

}

break;

}

if(p==v_amount)

{

for(p=0;p

{

if(tag[0][p]==left[j])

{

tag[1][p]='1';

tagt++;

break;

}

}

}

}

}

}

}

}while(tagt!

=0);

}

//计算first集

voidFirstComputer(charleft[],stringright[],chartag[][N/2],stringfirst[][N/2],intv_amount,intvn_amount)

{

boolrightAllVn;

intfirstNoNull;

intfirstNoNullTemp;

stringtemp;

stringchangeCheck;

inttagt;

do

{

//检测First集合是否还在增大

tagt=0;

for(inti=0;i

{

for(intj=0;j

{

firstNoNull=0;//标志量的位置不能设错

firstNoNullTemp=0;//这三个标志量分别表示该行第一个不能推出空的位置、该行右部都是非终结符

rightAllVn=1;

if(left[j]==first[0][i][0])//对每个非终结符X检查以其为左部的产生式

{

if((right[j][0]<'A'||right[j][0]>'Z')&&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->*

{

changeCheck=first[1][i];

first[1][i]=AddArray(first[1][i],right[j]);//*加入FIRST(X)

if(changeCheck!

=first[1][i])

tagt++;

continue;

}

/*for(intk=0;k

{

if(right[j][k]<'A'||right[j][k]>'Z')

{

rightAllVn=0;//对X推出的产生式右部只要有一个不是非终结符,rightAllVn=0

break;

}

}

*/

if(((right[j][0]<'A'||right[j][0]>'Z')&&right[j][0]!

='*')||right[j][0]=='*')

{

rightAllVn=0;

}

if(rightAllVn)//此产生式右部第一个是非终结符

{

for(intk=0;k

{

if((right[j][k]<'A'||right[j][k]>'Z')&&right[j][k]!

='*')

{

firstNoNull=k;

break;

}

for(intp=0;p

{

if(tag[0][p]==right[j][k])

{

if(tag[1][p]=='2')

{

firstNoNull++;//记录此产生式右部第一个不能推出空的非终结符位置

}

break;

}

}

if(firstNoNullTemp==firstNoNull)//如果第一个不能推出空的非终结符位置不变了,则找到了

{

break;

}

else

{

firstNoNullTemp=firstNoNull;

}

}

if(firstNoNull!

=right[j].length())//不是所有终结符都推出空

{

for(k=0;k

{

for(intp=0;p

{

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!

=first[1][i])

tagt++;

break;

}

}

}

if((right[j][firstNoNull]<'A'||right[j][firstNoNull]>'Z')&&right[j][firstNoNull]!

='*')

{

changeCheck=first[1][i];

first[1][i]=AddArray(first[1][i],string(1,right[j][firstNoNull]));

if(changeCheck!

=first[1][i])

tagt++;

}

else

{

for(intp=0;p

{

if(first[0][p][0]==right[j][firstNoNull])

{

changeCheck=first[1][i];

first[1][i]=AddArray(first[1][i],first[1][p]);//FIRST(X)加入FIRST(Yi)

if(changeCheck!

=first[1][i])

tagt++;

break;

}

}

}

}

else//所有终结符都推出空

{

for(intk=0;k

{

for(intp=0;p

{

if(first[0][p][0]==right[j][k])

{

changeCheck=first[1][i];

first[1][i]=AddArray(first[1][i],first[1][p]);//FIRST(X)中加入FIRST(Yn)

if(changeCheck!

=first[1][i])

tagt++;

break;

}

}

}

changeCheck=first[1][i];

first[1][i]=AddArray(first[1][i],"*");

if(changeCheck!

=first[1][i])

tagt++;

}

}

}

}

}

}while(tagt!

=0);

}

//计算follow集

voidFollowComputer(charleft[],stringright[],constchartag[][N/2],conststringfirst[][N/2],stringfollow[][N/2],intv_amount,intvn_amount)

{

intfirstNoNull;

intfirstNoNullTemp;

stringbeginSignal;

cout<<"Inputthebeginsignalofthegrammar:

";

cin>>beginSignal;

stringtempt;

stringtemp;

stringchangeCheck;

inttagt;

for(inti=0;i

{

if(follow[0][i]==beginSignal)

{

follow[1][i]=AddArray(follow[1][i],"#");

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

当前位置:首页 > 人文社科 > 广告传媒

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

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