编译原理实验文法的判断.docx

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

编译原理实验文法的判断.docx

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

编译原理实验文法的判断.docx

编译原理实验文法的判断

文法类型的判断和推导序列的生成

一、实验名称

文法类型的判断和推导序列的生成

二、实验目的

输入:

一组任意的文法规则和任意符号串。

输出:

相应的Chomsky文法类型和推导。

三、实验原理

1、文法G定义为四元组(Vn,Vt,P,S)

其中Vn为非终结符(或语法实体,或变量)集:

Vt为终结符集;P为规则(α->β)的集合,α∈(Vn∪Vt)*且至少包含一个非终结符,β∈(Vn∪Vt)*;Vn,Vt和P是非空有穷集。

S称作识别符或开始符,它是一个非终结符,至少要在一条规则中作为左部出现。

2、文法类型的判断

a.设G=(Vn,Vt,P,S)为一文法,若P中的每一个产生式α->β均满足

|β|>=|α|,仅仅S->ε除外,则文法G是1型或上下文有关的。

b.设G=(Vn,Vt,P,S),若P中的每一个产生式α->β满足:

α是一个非终结符,β∈(Vn∪Vt)*,则此文法称为2型的或上下文无关的。

c.设G=(Vn,Vt,P,S),若P中的每一个产生式的形式都是A->αB或A->α,其中A和B都是终结符,α∈Vt*,则G是3型文法或正规文法。

四、实验思路

本实验采取C++来完成,用大写字母A到Z表示非终结符,小写字符a到z表示终结符。

实验流程图

1、接受产生式

首先建立一个结构体siyuanzu,其成员有非终结符集合数组Vn,终结符集合数组Vt以及产生式集合数组rule,通过函数input来接受从键盘输入的产生式,并且存储于string类字符串数组rule中。

函数input实现接受产生式功能的思路为:

先确定要输入的产生式数目n,用for循环实现产生式的存储。

2、文法类型的判断

函数Grammer实现判断文法类型的功能并且输出文法的类型。

其实现功能的思路为:

a.对rule数组中每一个产生式进行判断,以“->”中的“-”作为判断条件,将产生式分为左部和右部分别计算左部和右部的长度。

若youb小于左部则不是1型文法。

输出0型文法;若右部大于或等于左部,则继续判断。

b.判断文法是否为2型文法,经过a步骤的执行,若文法为1型文法,只需在此基础上判断文法的左部是否只有一个非终结符。

通过判断条件zuo==1&&'A'<=a.rule[i][zuo-1]&&a.rule[i][zuo-1]<='Z'确定是否为2型文法,若不满足判断条件则为1型文法,进行输出,若满足则继续判断。

c.判断文法是否为3型文法,经过b步骤的执行,若文法为2型文法,只需在此基础上判断文法的右部是否为αB或α形式或者是Bα或α形式。

通过判断条件一((you==2)&&(a.rule[i][num+1]>='a')&&(a.rule[i][num+1]<='z')&&(a.rule[i][num+2]>='A')&&(a.rule[i][num+2]<='Z'))||((you==1)&&(a.rule[i][num+1]>='a')&&(a.rule[i][num+1]<='z'))判断是否满足αB或α形式,通过判断条件二((you==2)&&(a.rule[i][num+1]>='A')&&(a.rule[i][num+1]<='Z')&&(a.rule[i][num+2]>='a')&&(a.rule[i][num+2]<='z'))||((you==1)&&(a.rule[i][num+1]>='a')&&(a.rule[i][num+1]<='z'))判断是否满足Bα或α形式。

若所有产生式同时满足判断条件一或者同时满足判断条件二,则为3型文法进行输出。

否则为2型文法进行输出。

3、将文法以四元组形式输出

函数output实现输出文法四元组形式的功能。

具体思路为:

a.将存放产生式的string类数组rule一分为二,用x数组存放rule中所有的大写字母即非终结符,用y数组存放rule中所有的小写字母即终结符。

b.用双重for循环给x和y数组中重复的字符标记,重复的字符全部赋值为“!

c.将x数组中非“!

”元素赋值给非终结符集Vn,将y数组中非“!

”元素赋值给终结符集Vt。

d.按照格式分别输出非终结符集Vn,终结符集Vt,产生式P以及开始符S。

五、实验小结

我运用C++解决了此次实验的文法类型判断的问题,在实际解决问题的过程中,主要遇到了以下几个问题:

1、文法类型的判断条件

《编译原理》书本上给出了几类文法类型的定义,但是在实际的解决问题过程中,需要将书本上给的判断条件转换为C++语言中的判断条件,这需要对文法类型的定义有很好的理解。

我通过判断产生式右部是否大于等于左部确定1型文法,在此基础上判断产生式左部是否为一个非终结符确定2型文法,最后在2型文法的基础上判断产生式是否全部满足αB或α形式或者是Bα或α形式确定3型文法。

最终解决了文法类型判断条件的问题。

2、产生式的存储问题

实验要求最少输入五条产生式,我最初是选择用C语言解决存储问题,但是发现C语言中对于字符串的处理不够灵活,于是选择了C++来解决。

C++中可以用string类型来定义字符串数组,并且可以通过length函数求每个字符串的长度,这样给每条产生式的判断都带来了极大的便捷。

3、文法以四元组形式输出问题

实验需要输出文法的四元组,即需要输出非终结符集Vn,终结符集Vt,产生式P以及开始符S,由于我将产生式存储在string类数组rule中,因此,需要将rule中的元素分为两类,大写字母为非终结符,小写字母为终结符。

但是分好类的数组存在元素重复的问题,我通过一个双重for循环给重复元素标记为“!

”,再将非“!

”元素赋值给字符数组Vn和Vt,解决了元素重复问题。

最后需要安排一下输出的格式即解决了这个问题。

通过本次实验,我深入的了解了文法类型的判断,对于文法类型的判断也更加的熟练。

同时,对于文法的四元组的定义更加的熟悉,并且对于运用C++解决编译原理的问题有了一定的基础。

六、附件

1、源代码

#include

#include

usingnamespacestd;

structsiyuanzu

{

charVn[50];

charVt[50];

stringrule[20];

};

intinput(siyuanzu*a)

{

intn,i;

cout<<"请输入产生式数目:

";

cin>>n;

cout<<"请输入产生式:

\n";

for(i=0;i

cin>>(*a).rule[i];

returnn;

}

voidoutput(siyuanzua,intn)

{

inti,j,length,k1=0,k2=0,m1=0,m2=0;

charx[50],y[50];

for(i=0;i

{

length=a.rule[i].length();

for(j=0;j

{

if(a.rule[i][j]!

='-'&&a.rule[i][j]!

='>')

{

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

{

x[k1]=a.rule[i][j];

k1++;

}

else

{

y[k2]=a.rule[i][j];

k2++;

}

}

}

}

for(i=0;i

for(j=i+1;j

{

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

x[j]='!

';

}

for(i=0;i

{

if(x[i]!

='!

')

{

a.Vn[m1]=x[i];

m1++;

}

}

for(i=0;i

for(j=i+1;j

{

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

y[j]='!

';

}

for(i=0;i

{

if(y[i]!

='!

')

{

a.Vt[m2]=y[i];

m2++;

}

}

cout<<"四元组G=(Vn,Vt,P,S)"<

cout<<"其中非终结符Vn={";

for(i=0;i

cout<

cout<

cout<<"}";

cout<

cout<<"终结符Vt={";

for(i=0;i

cout<

cout<

cout<<"}";

cout<

cout<<"P由下列产生式组成:

"<

for(i=0;i

cout<

cout<<"开始符为:

S"<

}

voidGrammer(siyuanzua,intn)

{

inti,j,length,num,zuo,you;

charc;

for(i=0;i

{

num=0;

length=a.rule[i].length();

for(j=0;j

{

c=a.rule[i][j];

num++;

if(c=='-')

break;

}

zuo=num-1;

you=length-(num+1);

if(you>=zuo)

continue;

else

break;

}

if(i==n)

{

for(i=0;i

{

num=0;

length=a.rule[i].length();

for(j=0;j

{

c=a.rule[i][j];

num++;

if(c=='-')

break;

}

zuo=num-1;

if(zuo==1&&'A'<=a.rule[i][zuo-1]&&a.rule[i][zuo-1]<='Z')

continue;

else

break;

}

if(i==n)

{

for(i=0;i

{

num=0;

length=a.rule[i].length();

for(j=0;j

{

c=a.rule[i][j];

num++;

if(c=='-')

break;

}

you=length-(num+1);

if(((you==2)&&(a.rule[i][num+1]>='a')&&(a.rule[i][num+1]<='z')&&(a.rule[i][num+2]>='A')&&(a.rule[i][num+2]<='Z'))||((you==1)&&(a.rule[i][num+1]>='a')&&(a.rule[i][num+1]<='z')))

continue;

else

break;

}

if(i==n)

cout<<"文法类型:

3型文法"<

else

{

for(i=0;i

{

num=0;

length=a.rule[i].length();

for(j=0;j

{

c=a.rule[i][j];

num++;

if(c=='-')

break;

}

you=length-(num+1);

if(((you==2)&&(a.rule[i][num+1]>='A')&&(a.rule[i][num+1]<='Z')&&(a.rule[i][num+2]>='a')&&(a.rule[i][num+2]<='z'))||((you==1)&&(a.rule[i][num+1]>='a')&&(a.rule[i][num+1]<='z')))

continue;

else

break;

}

if(i==n)

cout<<"文法类型:

3型文法"<

else

cout<<"文法类型:

2型文法"<

}

}

else

cout<<"文法类型:

1型文法"<

}

else

cout<<"文法类型:

0型文法"<

}

intmain()

{

intn,r;

siyuanzua;

while

(1)

{

cout<<"--------------------文法类型判断(E21414020陈国柱)--------------------"<

cout<<"1.输入产生式"<

cout<<"2.输出文法类型及四元组"<

cout<<"3.结束"<

cout<<"输入功能号:

"<

cin>>r;

if(r>3||r<1)

{

do

{

cout<<"输入有误,重新输入"<

cin>>r;

}while(r<=3&&r>=1);

}

switch(r)

{

case1:

n=input(&a);break;

case2:

Grammer(a,n);output(a,n);break;

case3:

exit(0);break;

default:

break;

}

}

return0;

}

2、运行结果截图

a.实验开始图

b.非1型文法

c.1型文法

d.2型文法

e.3型文法

f.实验结束图

-----精心整理,希望对您有所帮助!

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

当前位置:首页 > 农林牧渔 > 林学

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

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