《消除左递归-编译原理实验》由会员分享,可在线阅读,更多相关《消除左递归-编译原理实验(28页珍藏版)》请在人人文库网上搜索。
1、编译原理实验报告实验名称:消除左递归______________实验时间:2015-05-27________________院 系:管理信息工程学院______________班 级:12级计算机科学技术____________学 号:2___________________姓 名:王博一__________________1、 实验目的:理解LL(1)文法中消除左递归的原理2、 实验原理:1直接左递归的消除消除产生式中的直接左递归是比较容易的。例如假设非终结符P的规则为:PP / 其中,是不以P开头的符号串。那么,我们可以把P的规则改写为如下的非直接左递归形式: PP PP / 这两条规则。
2、和原来的规则是等价的,即两种形式从P推出的符号串是相同的。设有简单表达式文法GE:EE+T/ TTT*F/ FF(E)/ I经消除直接左递归后得到如下文法:ETEE +TE/ TFTT *FT/ F(E)/ I考虑更一般的情况,假定关于非终结符P的规则为PP1 / P2 / Pn / 1 / 2 /m其中,i(I1,2,n)都不为,而每个j(j1,2,m)都不以P开头,将上述规则改写为如下形式即可消除P的直接左递归:P1 P / 2 P /m PP 1P / 2 P / n P /2间接左递归的消除直接左递归见诸于表面,利用以上的方法可以很容易将其消除,即把直接左递归改写成直接右递归。然而文法。
3、表面上不存在左递归并不意味着该文法就不存在左递归了。有些文法虽然表面上不存在左递归,但却隐藏着左递归。例如,设有文法GS:SQc/ cQRb/ bRSa/ a虽不具有左递归,但S、Q、R都是左递归的,因为经过若干次推导有SQcRbcSabcQRbSabQcabRSaQcaRbca就显现出其左递归性了,这就是间接左递归文法。消除间接左递归的方法是,把间接左递归文法改写为直接左递归文法,然后用消除直接左递归的方法改写文法。如果一个文法不含有回路,即形如PP的推导,也不含有以为右部的产生式,那么就可以采用下述算法消除文法的所有左递归。消除左递归算法:(1) 把文法G的所有非终结符按任一顺序排列,例如。
4、,A1,A2,An。(2) for (i1;i#include#define N 20char PNN; /规则集char QN; /规则集,存放间接左递归消除后的部分规则char RNN; /用来存放规则的初始值int r; /实际输入的规则的个数int direct(char PNN); /直接左递归函数int indirect(char PNN); /间接左递归函数void directRemove(char PNN); /消除直接左递归函数void indirectRemove(char PNN); /消除间接左递归函数int direct(char PNN) /定义直接左递归函数in。
5、t flag=0;for(int i=0;i0)printf(经判断该文法含有直接左递归!n);return 1; /属于直接接左递归else return 0; /不属于直接左递归int indirect(char PNN) /定义间接左递归函数int flag=0; for(int i=0;i0)break;if(flag0) printf(经判断该文法含有间接左递归!n);return 2; /属于间接左递归else return 0; /不属于间接左递归void directRemove(char PNN) /定义消除直接左递归的函数int j=4;for(int i=0;i1) co。
6、py+; /如果有相同左部则规则总数加一for(i=0;i=4;s-)Pi+ks+t-1=Pi+ks;for(int u=3;u=4;s-)Pcopy-1s+t-1=Pcopy-1s;for(int u=3;u连接,规则间用空格隔开);printf(n);for(int k=0;kr;k+)scanf(%s,Pk); printf(n);printf(即输入的文法规则为:n);for(k=0;kr;k+)printf(%sn,Pk);if(direct(P)=1)directRemove(P);else if(indirect(P)=2)indirectRemove(P);elseprintf(经判断该文法不含有左递归!n);实验效果图:消除文法直接左递归实例见下页:消除文法直接左递归实例如下:消除文法间接左递归实例1如下:消除文法间接左递归实例2如下。