关键词不能为空

当前您在: 主页 > 英语 >

编译原理实验:消除文法的左递归

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-01 18:56
tags:

-

2021年2月1日发(作者:comrade)



编译原理实验报告



实验名称


:


消除文法的左递归



实验时间


:


2015/5/28


院系:管理与信息工程学院



班级


:


12


级计算机科学与技术



学号:


0124


姓名


:


刘杨凡




1.


实验目的:



输入:任意的上下文无关文法。



输出:消除了左递归的等价文法。



2.


实验原理:



1


.直接左递归的消除



假设非终结符



P


的规则为:



P




P


a


/


B



其中,


B


是不以


P


开头的符号串。那么,我们可以把


P


的规则改写为如下的非直




左递归形式:


P



B


P


'


P'




oP


'


/


?



这两条规则和原来的规则是等价的,即两种形式从



P


推出的符号串是相同的。



设有简单表达式文法



G[E]




E



E+T/ T


T



T*F/ F

< br>F


—(


E


/ I


经消除直接左递归后得到如下文法:


< p>
E



TE


'



E


'



+TE


'


/


?



T



FT


'



T


'



*FT


'


/


?



F


—(< /p>


E



/ I


考虑更一般的情况,假定关于非终结符



P


的规则为



P




P


al


/ P


o2


/??/


P


a


n


/


B


i


/


B


/??/




其中,


a



1


=


1




2


,…,


n


)都不为?而每个


B



j


=


1




2


,…,


m


)都不以


P




头,将上述规则改写为如下形式即可消除



P


的直接左递归:



P



B


i


P'


/ B


P'


/


??/


B


m


P


'



P


'



a


1


P


'


/


a


2


P


'


/



/


a


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


的推导,也不含有以


&


为右部的产< /p>



生式,那么就可以采用下述算法消除文法的所有左递归。



消除左递归算法:



(1)



把文法


G


的所有非终结符按任一顺序排列,例如,



A


n




(2)



for


(


i


=


1




i<=n




i++


)



for


(


j


=


1


;


j<=i




1


;


j++


)



{


把形如


A


i


f


A


j


Y


的产生 式改写成



A


i



1



/


62



/


??/


&




其中


A


j


f 6


1


/


6


/??/


&


是关于的


A


j


全部规则;


< p>
消除


A


i


规则中的直接左 递


归;



}


A


i


, < /p>


A


2


,


…,




(3)



化简由


(


2


)


所得到的文法,即去掉多余的规则。



利用此算法可以将上


述文法进行改写,来消除左递归。



首先,令非终结符的排序为



R



Q



S

< p>
。对于


R


,


不存在直接左 递归。把


R






Q


中的相关规则中,贝


U


Q


的规则变为


Q< /p>


f


Sab/ ab/ b




代换后的


Q


不含有直接左递归,将其代入


S, S


的规则变为


S


f


Sabc/ abc/ bc/



c




此时,


S


存在直接左递归。在消除了



S


的直接左递归后,得到整个文法为:



S


f


abcS


'


/bcS'/ cS'


S'


f


abcS'/


&



Q


f


Sab/ ab/ b


R


f


Sa/ a


可以看到从文法开始符号



S


出发,永远无法达到



Q



R


,

< br>所以关于


Q



R


的规


则是多余的,将其删除并化简,最后得到文法



G[S]


为:



S


f


abcS'/ bcS


'


/cS'


S'


f


abcS'/


?



当然如果对文法非终结符排序的不 同,最后得到的文法在形式上可能不一



样,

< br>但它们都是等价的。例如,如果对上述非终结符排序选为



S



Q



R


,


那么最



后得到的文法



G[R]


为:



R


f


bcaR'/ caR'/ aR


R'


f


bcaR'/


?



容易证明上述两个文法是等价的。



3..


实验内容:



消除左递归算法:



(4)



把文法


G


的所有非终结符按任一顺序排列,例如,



A


n




(5)



for


(


i


=


1




i<=n




i++


)




A


1


,


A< /p>


2


,


…,





for


(


j


=


1


;


j<=i




1


;


j++


)



{


把形如


A


i



A


j


丫的产生式改写成



A


i


f


Si


Y & Y


??/


&




其中


A




S


/


&


/??/


&


k


是关于的


A


j


全部规则;

< p>


消除


A


i


规则中的直接左递归;



}



(


6


)


化简由


(


2


)


所得到的文法,即去掉多余的规则。



利用此算法可以将上述文法进行改写,来消除左递归。



注意事项:



指明是否存在左递归,



以及左递归的类型。



对于直接左递归,



可将其改为直



接右递归;对于间接左 递归


(


也称文法左递归


)


,则应按照算法给出非终结符不



同排 列的等价的消除左递归后的文法。


(


应该有

n


!



)


4.


代码实现


(


C


语言


)




#include


#include<> #include<> #define N 20


char P[N][N];


char Q[N]; char


R[N][N];


int r;



//


规则集



//


规则集


,


存放间接左递归消除后的部分规则


//


用来存放规则的初始值



//


实际输入的规则的个数



int direct(char P[N][N]);


int indirect(char P[N][N]); void directRemove(char P[N][N]); void indirectRemove(char


//


直接左递归函数



P[N][N]);


//


间接左递归函数



int direct(char P[N][N])


//< /p>


定义直


//


消除直接左递归函数



//


消除间接左递归函数



接左递归函数



{



int flag=0;


for(int i=0;i


{



if(P[i][3]==P[i][0])


{


//


右部字符中有与左部相同的符号




flag++;


break;


}


}





if(flag>0)


{


printf(


经判断该文法含有直接左递归



!n


属于直接接左递归



}



else




return 0; //


不属于直接左递归



}



int indirect(char P[N][N]) //


定义间接左递归函数



{



int flag=0;


for(int i=0;i


{



for(int k=1;k


{


if(P[i+k][0]==P[i][3])


{



flag++; break;


}


}




if(flag>0) break;


}


if(flag>0)


{



printf(


经判断该文法含有间接左递归



!n


return 2;


//


属于间接左递归



}



else


return 0; //


不属于间接左递归



}



void directRemove(char P[N][N]) //


定义消除直接左递归的函数



{



int j=4;


for(int i=0;i


{


if(P[i][3]==P[i][0])


{



P[i][3]=P[i][2];


P[i][2]=P[i][1];


P[i][1]='''; while(P[i][j]!=0)


j++;


P[i][j]=P[i][0];


P[i][j+1]=''';


for(int k=0;k<4;k++) //


包含空的一条规则



P[r][k]=P[i][k];


P[r][k]='*';


}




else


{


j=3;


while(P[i][j]!=0)


j++;


P[i][j]=P[i][0];


P[i][j+1]=''';


}


}




printf(


消除直接左递归后的文法为



:n


-


-


-


-


-


-


-


-



本文更新与2021-02-01 18:56,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/594616.html

编译原理实验:消除文法的左递归的相关文章

  • 余华爱情经典语录,余华爱情句子

    余华的经典语录——余华《第七天》40、我不怕死,一点都不怕,只怕再也不能看见你——余华《第七天》4可是我再也没遇到一个像福贵这样令我难忘的人了,对自己的经历如此清楚,

    语文
  • 心情低落的图片压抑,心情低落的图片发朋友圈

    心情压抑的图片(心太累没人理解的说说带图片)1、有时候很想找个人倾诉一下,却又不知从何说起,最终是什么也不说,只想快点睡过去,告诉自己,明天就好了。有时候,突然会觉得

    语文
  • 经典古训100句图片大全,古训名言警句

    古代经典励志名言100句译:好的药物味苦但对治病有利;忠言劝诫的话听起来不顺耳却对人的行为有利。3良言一句三冬暖,恶语伤人六月寒。喷泉的高度不会超过它的源头;一个人的事

    语文
  • 关于青春奋斗的名人名言鲁迅,关于青年奋斗的名言鲁迅

    鲁迅名言名句大全励志1、世上本没有路,走的人多了自然便成了路。下面是我整理的鲁迅先生的名言名句大全,希望对你有所帮助!当生存时,还是将遭践踏,将遭删刈,直至于死亡而

    语文
  • 三国群英单机版手游礼包码,三国群英手机单机版攻略

    三国群英传7五神兽洞有什么用那是多一个武将技能。青龙飞升召唤出东方的守护兽,神兽之一的青龙。玄武怒流召唤出北方的守护兽,神兽之一的玄武。白虎傲啸召唤出西方的守护兽,

    语文
  • 不收费的情感挽回专家电话,情感挽回免费咨询

    免费的情感挽回机构(揭秘情感挽回机构骗局)1、牛牛(化名)向上海市公安局金山分局报案,称自己为了挽回与女友的感情,被一家名为“实花教育咨询”的情感咨询机构诈骗4万余元。

    语文