文法的化简和改造编译原理.docx
《文法的化简和改造编译原理.docx》由会员分享,可在线阅读,更多相关《文法的化简和改造编译原理.docx(22页珍藏版)》请在冰豆网上搜索。
文法的化简和改造编译原理
深圳大学
实验报告
课程名称:
编译原理
实验名称:
文法的化简和改造
姓名:
学号:
班级:
实验日期:
第6周、第8周实验课
一.实验目的
1)编写文法的化简和改造程序;
二.实验环境
1)硬件环境:
计算机;
2)软件环境:
C/C++编译器;
三.实验内容
1.用C/C++语言编写方法的化简和改造程序,实现以下功能之一(如实现两个功能,则满分为110分;如实现三个功能,则满分为120分):
(1)无用符号和无用产生式的删除,参考课本中算法2.1和算法2.2。
(2)ε-产生式的消除,参考课本中算法2.3、2.4和2.5。
(3)单产生式的消除,参考课本中算法2.6。
从文件或终端中读入文法,并将化简和改造后的文法输出到另一文件或终端中。
文法的表示如下:
S->aS
S->W
S->U
U->a
V->bV
V->ac
W->aW
用空字符表示ε
用大写的拉丁字母表示文法的非终结符号,用小写的拉丁字母表示文法的终结符号,每个产生式占一行,第一个产生式的左部为开始符号。
在下面写出代码,并用课本2.4节中相应的例子进行验证,提供相应的截图(对窗口截图时先同时按alt和prtscn键,再按ctrl+v粘贴)
答:
课本中的结果为:
S->aSS->UU->a
而在实验中输出结果为:
S->aSS->a
下面是书本中算法的主要代码:
//algorithm21,algorithm22用于消除无用产生式
//算法2.1
voidalgorithm21()
{
SymbolSetVN1;
ProductionSetP1;
structLnode*left=NULL;
structRnode*right=NULL;
intflag=0,added=1;
VN1.next=NULL;
P1.next=NULL;
P1.num=0;
//第一步
left=Productions.next;
while(left)
{
flag=1;
right=left->right;
while(right)
{
if(strcmp(right->name,"")==0)
break;
if(IsInSet(&Terminators,right->name)==0)
{
flag=0;
break;
}
right=right->next;
}
if(flag==1)
{
//如果原来不存在则添加
if(IsInSet(&VN1,left->name)==0)
AddSym(&VN1,left->name);
}
left=left->next;
}
//第二步
added=1;
while(added)
{
added=0;
left=Productions.next;
while(left)
{
flag=1;
right=left->right;
while(right)
{
if(strcmp(right->name,"")==0)
break;
if((IsInSet(&Terminators,right->name)==0)&&(IsInSet(&VN1,right->name)==0))
{
flag=0;
break;
}
right=right->next;
}
if(flag==1)
{
//如果原来不存在则添加
if(IsInSet(&VN1,left->name)==0)
{
AddSym(&VN1,left->name);
added=1;
}
}
left=left->next;
}
}
//第三步
left=Productions.next;
while(left)
{
flag=1;
right=left->right;
while(right)
{
if(strcmp(right->name,"")==0)
break;
if((IsInSet(&Terminators,right->name)==0)&&(IsInSet(&VN1,right->name)==0))
{
flag=0;
break;
}
right=right->next;
}
if(flag==1)
AddPro(&P1,left);
left=left->next;
}
//转移到系统链表集合
{
//删除原有的
ClearProductionSet(&Productions);
DestroySymbolSet(&NonTerminators);
//转移
Productions.num=P1.num;
Productions.next=P1.next;
NonTerminators.next=VN1.next;
}
}
//算法2.2
voidalgorithm22()
{
SymbolSetVN1,VT1;
ProductionSetP1;
structLnode*left=NULL;
structRnode*right=NULL;
intflag=0,added=1;
VN1.next=NULL;
VT1.next=NULL;
P1.next=NULL;
P1.num=0;
//开始符号放入VN1
AddSym(&VN1,Start);
//第一步
added=1;
while(added)
{
added=0;
left=Productions.next;
while(left)
{
if(IsInSet(&VN1,left->name)==1)
{
right=left->right;
while(right)
{
if(IsInSet(&NonTerminators,right->name)==1)
added=AddSym(&VN1,right->name);
elseif(IsInSet(&Terminators,right->name)==1||strcmp(right->name,"")==0)
added=AddSym(&VT1,right->name);
right=right->next;
}
}
left=left->next;
}
}
//第二步
left=Productions.next;
while(left)
{
flag=1;
if(IsInSet(&VN1,left->name)==1)
{
right=left->right;
while(right)
{
if(IsInSet(&VN1,right->name)==0&&IsInSet(&VT1,right->name)==0)
{
flag=0;
break;
}
right=right->next;
}
if(flag==1)
AddPro(&P1,left);
}
left=left->next;
}
//转移到系统链表集合
{
//删除原有的
ClearProductionSet(&Productions);
DestroySymbolSet(&NonTerminators);
DestroySymbolSet(&Terminators);
//转移
Productions.num=P1.num;
Productions.next=P1.next;
NonTerminators.next=VN1.next;
Terminators.next=VT1.next;
}
}
//algorithm23,algorithm24用于消除ε-产生式
//算法2.3
voidalgorithm23()
{
structLnode*left=NULL;
structRnode*right=NULL;
intflag=0,added=1;
W1.next=NULL;
W2.next=NULL;
//第一步
left=Productions.next;
while(left)
{
right=left->right;
//如果是空产生式
if((right->next==NULL)&&strcmp(right->name,"")==0)
AddSym(&W1,left->name);
left=left->next;
}
//第二步
added=1;
while(added)
{
added=0;
left=Productions.next;
while(left)
{
flag=1;
right=left->right;
while(right)
{
if(IsInSet(&W1,right->name)==0)
{
flag=0;
break;
}
right=right->next;
}
if(flag==1)
added=AddSym(&W1,left->name);
left=left->next;
}
}
//algorithm23结束,等待算法2.4
}
//算法2.4
voidalgorithm24()
{
ProductionSetP1;
structSymbol*sym=NULL;
structLnode*left=NULL,*ltmp=NULL,*tmpNew=NULL;
structRnode*right=NULL,*rtmp=NULL;
intflag=0,added=1;
P1.next=NULL;
P1.num=0;
//第一步
sym=NonTerminators.next;
while(sym)
{
if(IsInSet(&W1,sym->name)==0)
AddSym(&W2,sym->name);
sym=sym->next;
}
//第二步
left=Productions.next;
while(left)
{
tmpNew=(structLnode*)malloc(sizeof(structLnode));
tmpNew->name=(char*)malloc(strlen(left->name)+1);
strcpy(tmpNew->name,left->name);
tmpNew->next=NULL;
tmpNew->right=NULL;
forAlgo24(&P1,left,left->right,tmpNew);
left=left->next;
}
//转移
ClearProductionSet(&Productions);
Productions.next=P1.next;
Productions.num=P1.num;
}
//递归添加产生式
voidforAlgo24(ProductionSet*Set,structLnode*left,structRnode*tail,structLnode*p)
{
structLnode*ltmp=NULL,*new1=NULL,*new2=NULL;
structRnode*rtmp=NULL,*rt1=NULL,*rt2=NULL,*tailTmp=NULL;;
if(tail==NULL)
{
rtmp=p->right;
if(strcmp(rtmp->name,"")==0&&rtmp->next==NULL)
return;
else
AddPro(Set,p);
}
elseif(IsInSet(&W1,left->name)==0)
{
//复制p
new1=(structLnode*)malloc(sizeof(structLnode));
new1->name=(char*)malloc(strlen(p->name)+1);
strcpy(new1->name,p->name);
new1->next=NULL;
new1->right=NULL;
rt1=p->right;
while(rt1)
{
rt2=(structRnode*)malloc(sizeof(structRnode));
rt2->name=(char*)malloc(strlen(rt1->name)+1);
strcpy(rt2->name,rt1->name);
rt2->next=NULL;
if(new1->right==NULL)
{
new1->right=rt2;
tailTmp=new1->right;
}
else
{
tailTmp->next=rt2;
tailTmp=tailTmp->next;
}
rt1=rt1->next;
}
rt2=(structRnode*)malloc(sizeof(structRnode));
rt2->name=(char*)malloc(strlen(tail->name)+1);
strcpy(rt2->name,tail->name);
rt2->next=NULL;
if(tailTmp==NULL)
new1->right=rt2;
else
tailTmp->next=rt2;
forAlgo24(Set,left,tail->next,new1);
}
else
{
//复制p,1
new1=(structLnode*)malloc(sizeof(structLnode));
new1->name=(char*)malloc(strlen(p->name)+1);
strcpy(new1->name,p->name);
new1->next=NULL;
new1->right=NULL;
rt1=p->right;
while(rt1)
{
rt2=(structRnode*)malloc(sizeof(structRnode));
rt2->name=(char*)malloc(strlen(rt1->name)+1);
strcpy(rt2->name,rt1->name);
rt2->next=NULL;
if(new1->right==NULL)
{
new1->right=rt2;
tailTmp=new1->right;
}
else
{
tailTmp->next=rt2;
tailTmp=tailTmp->next;
}
rt1=rt1->next;
}
rt2=(structRnode*)malloc(sizeof(structRnode));
rt2->name=(char*)malloc(strlen(tail->name)+1);
strcpy(rt2->name,tail->name);
rt2->next=NULL;
if(tailTmp==NULL)
new1->right=rt2;
else
tailTmp->next=rt2;
forAlgo24(Set,left,tail->next,new1);
new1=NULL;
rt1=rt2=tailTmp=NULL;
/////////////////////////////////////////////////
//复制p,2
new2=(structLnode*)malloc(sizeof(structLnode));
new2->name=(char*)malloc(strlen(p->name)+1);
strcpy(new2->name,p->name);
new2->next=NULL;
new2->right=NULL;
rt1=p->right;
while(rt1)
{
rt2=(structRnode*)malloc(sizeof(structRnode));
rt2->name=(char*)malloc(strlen(rt1->name)+1);
strcpy(rt2->name,rt1->name);
rt2->next=NULL;
if(new2->right==NULL)
{
new1->right=rt2;
tailTmp=new1->right;
}
else
{
tailTmp->next=rt2;
tailTmp=tailTmp->next;
}
rt1=rt1->next;
}
forAlgo24(Set,left,tail->next,new2);
}
ClearLNode(p);
}
//算法2.5
voidalgorithm25()
{
structLnode*left=NULL;
structRnode*right=NULL;
intflag=0,added=1;
chartemp[MAXLEN]={'\0'};
memset(temp,0,MAXLEN);
//首先判断开始符号是否出现在产生式右部
left=Productions.next;
flag=0;
while(left&&flag==0)
{
right=left->right;
while(right)
{
if(strcmp(Start,right->name)==0)
{
flag=1;
break;
}
right=right->next;
}
left=left->next;
}
}
//算法2.6
voidalgorithm26()
{
ProductionSetP1;
SymbolSetW;
structLnode*left=NULL,*ltmp=NULL;
structRnode*right=NULL,*rtmp=NULL;
structSymbol*sym=NULL;
intflag=0,added=1;
P1.next=NULL;
P1.num=0;
W.next=NULL;
left=Productions.next;
while(left)
{
added=1;
while(added)
{
added=0;
added=AddSym(&W,left->name);
ltmp=Productions.next;
while(ltmp)
{
if(IsInSet(&W,ltmp->name)==1)
{
rtmp=ltmp->right;
if((IsInSet(&NonTerminators,rtmp->name)==1)&&(NULL==rtmp->next))
added=AddSym(&W,rtmp->name);
}
ltmp=ltmp->next;
}
}
//第二步
sym=W.next;
while(sym)
{
ltmp=Productions.next;
while(ltmp)
{
if(strcmp(sym->name,ltmp->name)==0)
{
rtmp=ltmp->right;
if(rtmp->next!
=NULL||IsInSet(&NonTerminators,rtmp->name)==0)
AddPro1(&P1,&P1,left,ltmp);
}
ltmp=ltmp->next;
}
sym=sym->next;
}
DestroySymbolSet(&W);
left=left->next;
}
/