编译原理实验二压缩文法等价变换.docx
- 文档编号:11942908
- 上传时间:2023-04-16
- 格式:DOCX
- 页数:12
- 大小:53.88KB
编译原理实验二压缩文法等价变换.docx
《编译原理实验二压缩文法等价变换.docx》由会员分享,可在线阅读,更多相关《编译原理实验二压缩文法等价变换.docx(12页珍藏版)》请在冰豆网上搜索。
编译原理实验二压缩文法等价变换
实验二:
压缩文法的等价变换
一:
要求
输入:
任意的上下文无关文法
输出:
等价的压缩了的文法
要求:
除了可查看压缩了的文法,还可查看删除了哪些规则
二:
实验目的
了解文法的简化
三:
实验原理
删除文法中的有害规则和多余规则
有害规则:
若文法中有如U:
:
=U的规则,则这就是有害规则,它会引
起二义性,而无任何用处。
多余规则:
(1)某条规则U:
:
=u的左部非终结符U(U不是识别符号),不在任何其他规则右部出现,即所有的推导始终不会用到此规则。
【不可到达】
(2)在推导句子的过程中,一旦使用了该规则,将推不出任何终结符号串。
即该规则中含有推不出任何终结符号串的非终结符。
【不可终止】
四:
数据结构与算法
structChomsky
{
stringleft;
stringright;
};
voidapart(Chomsky*p,inti)//分开产生式左右部
voidVNVT(Chomsky*p)//求VN和VT
intzero(Chomsky*p)//0型文法
intone(Chomsky*p)//1型文法
inttwo(Chomsky*p)//2型文法
voidshanchu(Chomsky*p)//删除多余规则与有害规则
五:
出错分析
1:
变量重复定义导致了一些小错误
2:
程序太长{}缺少也导致了错误
3:
后面删除规则的程序出错了,没有调试成功。
六:
实验结果与分析
不是上下文无关文法的:
2型文法的压缩:
七:
源代码
#include
#include
usingnamespacestd;
#definemax50
intNONE=1;
intRELEFT=1;
stringstrings,noend,end;//非终结符与终结符存储
intn;//产生式总数
intflag;
structChomsky
{
stringleft;
stringright;
};
voidapart(Chomsky*p,inti)//分开产生式左右部
{
intj;
for(j=0;j if(strings[j]=='-') { p[i].left=strings.substr(0,j); p[i].right=strings.substr(j+1,strings.length()-j); } } voidVNVT(Chomsky*p)//求VN和VT { inti,j; for(i=0;i { for(j=0;j<(int)p[i].left.length();j++) { if((p[i].left[j]>='A'&&p[i].left[j]<='Z'))//非终结符判断 { if(noend.find(p[i].left[j])>100) noend+=p[i].left[j]; } else { if(end.find(p[i].left[j])>100) end+=p[i].left[j]; } } for(j=0;j<(int)p[i].right.length();j++) { if(! (p[i].right[j]>='A'&&p[i].right[j]<='Z'))//终结符判断 { if(end.find(p[i].right[j])>100) end+=p[i].right[j]; } else { if(noend.find(p[i].right[j])>100) noend+=p[i].right[j]; } } } } intzero(Chomsky*p)//0型文法 { intflag(0),count(0); inti,j; for(i=0;i { for(j=0;j<(int)p[i].left.length();j++) { if(p[i].left[j]>='A'&&p[i].left[j]<='Z')//有否非终结符 flag++; } if(flag>0) { flag=0; count++; } else break;//左部没有非终结符,结束 } if(count==n) return1;//属于0型文法 else { cout< "< NONE=0; return0; } } intone(Chomsky*p)//1型文法 { intflag(0); inti; if(zero(p)) { for(i=0;i { if(p[i].right.length() { flag++; break; } } } else flag--; if(flag>0) { cout< "< return0;//不属于1型文法 } else if(flag==0) return1;//属于1型文法 else return0; } inttwo(Chomsky*p)//2型文法 { intflag(0); inti; if(one(p)) { for(i=0;i if((p[i].left.length()! =1)||! (p[i].left[0]>='A'&&p[i].left[0]<='Z'))//左部不属于一个字符或不属于非终结符 { flag++; break; } } else flag--; if(flag>0) { cout< "< return0;//不属于2型文法 } else if(flag==0) { cout<<"次文法属于2型文法"< return1;//属于2型文法 } else return0; } voidshanchu(Chomsky*p)//删除多余规则与有害规则 { if(two(p)) { cout<<"此文法属于上下文无关文法,可进行文法压缩,实验继续"< inti,j; for(i=0;i { if(p[i].left.length()==p[i].right.length()) { for(j=0;j<(int)p[i].left.length();j++) { if(p[i].left[j]! =p[i].right[j])//不为有害规则 { j--; break;//次规则不是有害规则 } } if(j==p[i].left.length()-1)//此条规则为有害规则,删除 { cout<<"删除此条有害规则"< "< n--; } } } for(intk=0;k<(int)noend.length();k++)//多余规则中不可到达的判断 { for(i=0;i { for(j=0;j<(int)p[i].right.length();j++) { if(noend[k]! =p[i].right[j]) continue; else i--;break; } if(i==n-1)//此条规则为多余规则 { for(i=0;i { if(p[i].left[j]==noend[k]||p[i].right[j]==noend[k]) cout<<"删除此条多余规则"< "< n--; } } } } for(k=0;k<(int)noend.length();k++)//多余规则中不可终止的判断 { } cout<<"压缩后的文法是: "< for(i=0;i { cout< "< } } else cout<<"此文法不是上下文无关文法,实验结束"< } voidmain() { inti; cout<<"....................编译原理实验二: 压缩文法的等价变换...................."< cout<<"请输入产生式总数及各产生式: "< cin>>n; Chomsky*p=newChomsky[max]; for(i=0;i { cin>>strings; apart(p,i); } VNVT(p); shanchu(p); }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 压缩 文法 等价 变换