首页 c实现消除文法左递归

c实现消除文法左递归

举报
开通vip

c实现消除文法左递归编译原理实验报告 实验名称        消除文法的左递归                            实验时间              2010.11.1                          院系            计算机科学与技术                              班级                    2008                            学号                  JB084193           ...

c实现消除文法左递归
编译原理实验 报告 软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载 实验名称        消除文法的左递归                            实验时间              2010.11.1                          院系            计算机科学与技术                              班级                    2008                            学号                  JB084193                      姓名                    潘亚飞                          1.试验目的 输入:任意的上下文无关文法。 输出:消除了左递归的等价文法。 2.实验原理 1.直接左递归的消除 消除产生式中的直接左递归是比较容易的。例如假设非终结符P的规则为 P→Pα / β 其中,β是不以P开头的符号串。那么,我们可以把P的规则改写为如下的非直接左递归形式:                      P→βP’ P’→αP’ / ε 这两条规则和原来的规则是等价的,即两种形式从P推出的符号串是相同的。 设有简单 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 达式文法G[E]: E→E+T/ T T→T*F/ F F→(E)/ I 经消除直接左递归后得到如下文法: E→TE’ E’ →+TE’/ ε T→FT’ T’ →*FT’/ ε F→(E)/ I 考虑更一般的情况,假定关于非终结符P的规则为 P→Pα1 / Pα2 /…/ Pαn / β1 / β2 /…/βm 其中,αi(I=1,2,…,n)都不为ε,而每个βj(j=1,2,…,m)都不以P开头,将上述规则改写为如下形式即可消除P的直接左递归: P→β1 P’ / β2 P’ /…/βm P’ P’ →α1P’ / α2 P’ /…/ αn P’ /ε 2.间接左递归的消除 直接左递归见诸于表面,利用以上的方法可以很容易将其消除,即把直接左递归改写成直接右递归。然而文法表面上不存在左递归并不意味着该文法就不存在左递归了。有些文法虽然表面上不存在左递归,但却隐藏着左递归。例如,设有文法G[S]: S→Qc/ c Q→Rb/ b R→Sa/ a 虽不具有左递归,但S、Q、R都是左递归的,因为经过若干次推导有 S Qc Rbc Sabc Q Rb Sab Qcab R Sa Qca Rbca 就显现出其左递归性了,这就是间接左递归文法。 消除间接左递归的方法是,把间接左递归文法改写为直接左递归文法,然后用消除直接左递归的方法改写文法。 如果一个文法不含有回路,即形如P P的推导,也不含有以ε为右部的产生式,那么就可以采用下述算法消除文法的所有左递归。 消除左递归算法: (1) 把文法G的所有非终结符按任一顺序排列,例如,A1,A2,…,An。 (2) for (i=1;i<=n;i++) for (j=1;j<=i-1;j++) {    把形如Ai→Ajγ的产生式改写成Ai→δ1γ /δ2γ /…/δkγ 其中Aj→δ1 /δ2 /…/δk是关于的Aj全部规则; 消除Ai规则中的直接左递归; } (3) 化简由(2)所得到的文法,即去掉多余的规则。 利用此算法可以将上述文法进行改写,来消除左递归。 首先,令非终结符的排序为R、Q、S。对于R,不存在直接左递归。把R代入到Q中的相关规则中,则Q的规则变为Q→Sab/ ab/ b。 代换后的Q不含有直接左递归,将其代入S,S的规则变为S→Sabc/ abc/ bc/ c。 此时,S存在直接左递归。在消除了S的直接左递归后,得到整个文法为: S→abcS’/ bcS'/ cS' S’ →abcS'/ ε Q→Sab/ ab/ b R→Sa/ a 可以看到从文法开始符号S出发,永远无法达到Q和R,所以关于Q和R的规则是多余的,将其删除并化简,最后得到文法G[S]为: S→abcS'/ bcS’/ cS' S' →abcS'/ ε 当然如果对文法非终结符排序的不同,最后得到的文法在形式上可能不一样,但它们都是等价的。例如,如果对上述非终结符排序选为S、Q、R,那么最后得到的文法G[R]为:        R→bcaR'/ caR'/ aR’ R' →bcaR'/ ε 容易证明上述两个文法是等价的。 3..实验内容 消除左递归算法: (1)把文法G的所有非终结符按任一顺序排列,例如,A1,A2,…,An。 (2)for (i=1;i<=n;i++) for (j=1;j<=i-1;j++) {    把形如Ai→Ajγ的产生式改写成Ai→δ1γ /δ2γ /…/δkγ 其中Aj→δ1 /δ2 /…/δk是关于的Aj全部规则; 消除Ai规则中的直接左递归; } (3)化简由(2)所得到的文法,即去掉多余的规则。 利用此算法可以将上述文法进行改写,来消除左递归。 4.实验代码 //#include "stdafx.h" #include #include using namespace std; struct WF      //定义一个产生式结构体 { string left; //定义产生式的左部 string right; //定义产生式的右部 }; void Removing(WF *p,char *q,int n,int count) { int count1=n; int flag=0; for(int i=0;i < n;i++)//判断第一个非终结符是否存在直接左递归 if(p[i].left[0]==q[0]) if(p[i].left[0]==p[i].right[0]) flag++; if(flag!=0)//如果存在直接左递归则消除直接左递归 { for(int i=0;i < n;i++) if(p[i].left[0]==q[0]) if(p[i].left[0]==p[i].right[0]) { string str; str=p[i].right.substr(1,int (p[i].right.length())); string temp=p[i].left; string temp1="'"; p[i].left=temp+temp1; p[i].right=str+p[i].left; } else { string temp=p[i].left; string temp1="'"; temp=temp+temp1; p[i].right=p[i].right+temp; } string str="'"; p[count1].left=p[0].left[0]+str; p[count1].right="ε"; } for( i=0;i <= count;i++) { for(int j=0;j < i;j++) { for(int g=0;g < n;g++) if(q[i]==p[g].left[0]) if(p[g].right[0]==q[j]) { for(int h=0;h < n*n;h++) if(p[h].left[0]==q[j]&&int (p[h].left.length())==1) { string str; str=p[g].right.substr(1,int (p[g].right.length())); p[++count1].left=p[g].left; p[count1].right=p[h].right+str; } p[g].left=""; p[g].right=""; } } } for( i=0;i <= count;i++) { flag=0; for(int j=0;j < n*n;j++) if(p[j].left[0]==q[i]) if(p[j].left[0]==p[j].right[0]) flag++; if(flag!=0) { for(int j=0;j <= n*n;j++) if(p[j].left[0]==q[i]) if(p[j].left[0]==p[j].right[0]) { string str; str=p[j].right.substr(1,int (p[j].right.length())); string temp=p[j].left; string temp1="'"; p[j].left=temp+temp1; p[j].right=str+p[j].left; } else { string temp=p[j].left; string temp1="'"; temp=temp+temp1; p[j].right=p[j].right+temp; } string str="'"; p[++count1].left=q[i]+str; p[count1].right="ε"; } } } int Delete(WF *p,int n) { return 0; } int main() { int i,j,flag=0,count=1,n; cout<<"请输入文法产生式个数n:"<>n; WF *p=new WF[50]; cout<<"请输入文法的个产生式:"<>p[i].left; cout<<"->"<>p[i].right; cout<"<"<"< 心得 信息技术培训心得 下载关于七一讲话心得体会关于国企改革心得体会关于使用希沃白板的心得体会国培计划培训心得体会 一个文法是含有左递归的,如果存在非终结符P ,P Pα 含有左递归的文法将使上述的自上而下的分析过程陷入无限循环,即当试图用P去匹配输入串时,就会出现在没有吃进任何输入符号的情况下,又得重新要求P去进行新的匹配。因此,使用自上而下分析法必须消除文法的左递归性。 对文法中一切左递归的消除要求文法中不含回路即无A A的推导。满足这个要求的充分条件是:文法中不包含形如A→A和A→ε的空产生式。 根据消除左递归的算法步骤我们可以得出整个程序思路。对于产生式的存储问题,采用定义产生式的结构体,再用表的形式来存储所有的产生式。再输入存储时就将产生式的左部和右部分开存储于产生式结构体中,方便后面的操作。在消除左递归的过程中,对于直接左递归,可将其改为直接右递归;对于间接左递归(也称文法左递归),则应按照算法给出非终结符不同排列的等价的消除左递归后的文法。
本文档为【c实现消除文法左递归】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_219945
暂无简介~
格式:doc
大小:50KB
软件:Word
页数:16
分类:互联网
上传时间:2019-04-21
浏览量:50