编译原理文法的判别实验报告.docx
《编译原理文法的判别实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理文法的判别实验报告.docx(9页珍藏版)》请在冰豆网上搜索。
编译原理文法的判别实验报告
编译原理文法的判别实验报告
编译原理实验报告
实验名称文法类型的判别实验时间2013年11月2日
院系安徽大学江淮学院
学号JV114025
姓名张巧巧
学号JV114002
姓名王文悦
学号JV114045
姓名冯岚
文法类型的判别
1.实验目的
1)、检测对文法类型的掌握程度
2)、加深对文法的理解
3)、练习用编程解决问题
4)、培养动手能力与创作思维
2.实验原理
1)、0型文法(短语文法)
设G=(Vn,Vt,P,S),如果它的每一个产生式#->&是这样一种结构:
#属于(终结符和终结符)的闭包且至少含有一个非终结符,&属于(终结符和终结符)的闭包。
任何0型语言都是递归可枚举的,递归可枚举集必定是一个0型文法,0型文法的能力相当于图灵机(Turning)。
2)、1型文法(上下文有关文法)
设G=(Vn,Vt,P,S)为一文法,若P中的每一个产生式#->&均满足|#|>=|&|,仅仅S->空除外。
其识别系统:
线性界限自动机
3)、2型文法(上下文无关文法)
设G=(Vn,Vt,P,S)为一文法,若P中的每一个产生式#->&均满足:
#是一个非终结符,&属于(终结符和终结符)的闭包。
2型文法其识别系统:
不确定的下推自动机
1
一般定义程序设计语言的文法是上下文无关的。
如C语言便是如此。
因此,上下文无关文法及相应语言引起了人们较大的兴趣与重视。
4)、3型文法(正规文法)
设G=(Vn,Vt,P,S)为一文法,若P中的每一个产生式都是A->aB或A->a,其中A和B都是非终结符,a属于终结符的闭包。
其识别系统:
确定的有穷自动机
可以看出上述4类文法,从0型到3型,产生式的限制越来越强,其后一类都是前一类的子集,而描述语言的功能越来越弱,四类文法之间的关系可表示为:
0型>1型>2型>3型
3.实验内容
1)、输入文法的终结符(小写字母或数字)和非终结符(大写字母)以及确定识别符(规定第一输入的非终结符为识别符)
2)、输入文法的产生式的个数以及各个产生式(左部->右部)
3)、判断文法类型
4.实验心得
通过这次实验让我们深深的体会到了判别文法的复杂性,也走了许多冤枉路,想过多种方法,尝试过,可是有的没有走下去,最终没有出我们知道文法是嵌套的,也就是说满足3型文法的条件,一定是2型、1型、0型文法;满足2型文法的条件,一定是1型、0型文法;满足1型文法一定是0型文法;利用这一特点着手判断,先判断一条产生式是否满足3型文法,如果不是3型文法然后判断是否是2型文法、1型文法、0型文法,直到判断最精确的文法类型。
在过程中从
2
一条产生式的0型文法开始判断,若发现上一条规则是符合1型文法,则就从1型文法开始判断,详见源代码。
5.实验代码与结果
1)、实验代码
#define_CRT_SECURE_NO_WARNINGS#include
#include
#include
#include
#include
#include
usingnamespacestd;
constintSTRING_MAX_LENGTH=10;
/*一条规则*/
structPrinciple{
stringleft;
stringright;
Principle(constchar*l,constchar*r):
left(l),right(r){}
};
/*文法的四元组形式,同时将该文法类型也作为其属性*/
structGrammer{
setVn;
setVt;
vectorP;
charS;
intflag;//文法类型
Grammer(void):
flag(-1){}};
/*输入规则*/
voidinput(vector&principleSet){
charleft[STRING_MAX_LENGTH];
charright[STRING_MAX_LENGTH];
while(EOF!
=scanf("%[^-]->%s",left,right))
{
getchar();
principleSet.push_back(Principle(left,right));
}
}
3
/*得到S,Vn,Vt*/
voidgetGrammer(Grammer&G){
G.S=G.P.front().left.front();
G.Vn.clear();
G.Vt.clear();
for(unsignedi=0;i{
constPrinciple&prcp=G.P[i];
for(unsignedj=0;j{
charv=prcp.left[j];
!
isupper(v)?
G.Vt.insert(v):
G.Vn.insert(v);
}
for(unsignedj=0;j{
charv=prcp.right[j];
!
isupper(v)?
G.Vt.insert(v):
G.Vn.insert(v);
}
}
}
/*判断字符串(文法的左部)中是否存在一个非终结符。
*/
boolhasUpper(strings)
{
returns.end()!
=find_if(s.begin(),s.end(),isupper);}
/*判断文法类型。
*/
voidcheck(int&flag,constPrinciple&prcp)
{
switch(flag){
case3:
if(1==prcp.left.size()&&isupper(prcp.left.front())&&
(1==prcp.right.size()&&!
isupper(prcp.right.front())||
2==prcp.right.size()&&!
isupper(prcp.right.front())&&isupper(prcp.right.back())))
{
break;
}
case2:
if(1==prcp.left.size()&&isupper(prcp.left.front()))
4
{
flag=2;
break;
}
case1:
if(hasUpper(prcp.left)&&prcp.left.size()<=prcp.right.size())
{
flag=1;
break;
}
default:
//所有的文法规则左部都必须至少含有一个非终结符,是否应放到最前面判断,
//用异常机制exit是否合适,
try{
if(!
hasUpper(prcp.left)){
throwexception("输入的文法错误~");
}
}
catch(exceptione){
cout<exit(-1);
}
flag=0;
break;
}
}
/*判别文法并生成四元组形式。
*/
voidsolve(Grammer&G){
G.flag=3;//从正则文法开始判断
for(unsignedi=0;i{
check(G.flag,G.P[i]);
}
getGrammer(G);
}
/*输出文法*/
voidoutput(constGrammer&G){
cout<<"G=(Vn,Vt,P,S)是"<5
cout<<"Vn:
"<for(autoite=G.Vn.begin();ite!
=G.Vn.end();++ite)
{
cout<<*ite<}
cout<cout<<"Vt:
"<for(autoite=G.Vt.begin();ite!
=G.Vt.end();++ite)
{
cout<<*ite<}
cout<cout<<"P:
"<for(autoite=G.P.begin();ite!
=G.P.end();++ite)
{
cout<<(*ite).left<<"->"<<(*ite).right<}
cout<cout<<"S:
\n"<intmain(intargc,char**argv){
freopen("cin.txt","r",stdin);
GrammerG;
input(G.P);
solve(G);
output(G);
return0;
}
2)、结果
输入:
S->aSBES->aBEEB->BEaB->abbB->bbbE->beeE->ee
6
输入:
S->aBS->bAA->aA->aSA->bAAB->bB->bSB->aBB
输出:
7