关键词不能为空

当前您在: 主页 > 英语 >

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

作者:高考题库网
来源: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

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

  • 爱心与尊严的高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊严高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊重的作文题库

    1.作文关爱与尊重议论文 如果说没有爱就没有教育的话,那么离开了尊重同样也谈不上教育。 因为每一位孩子都渴望得到他人的尊重,尤其是教师的尊重。可是在现实生活中,不时会有

    小学作文
  • 爱心责任100字作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任心的作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文