char ch=gene[i][0];
bool rg=false;
while(sss!=string::npos)
{
eee=gene[i].find_first_of("|",sss+1);
if(eee==string::npos)eee=gene[i].length();
if(gene[i][sss]==ch)
{
rg=true;
p1+=gene[i].substr(sss+1,eee-sss-1)+ch+"\'|";
}
else
{
p2+=gene[i].substr(sss,eee-sss)+ch+"\'|";
}
sss=gene[i].find_first_not_of("|",eee+1);
}
p2[p2.length()-1]='\0';
if(rg)
{
temp[count2]=ch+("\'->"+p1+"ε");
count2++;
gene[i].replace(3,gene[i].length()-3,p2);
}
}
cout<<"消除递归后的文法为:"<
消除间接左递归:
6.实验心得
一个文法是含有左递归的,如果存在非终结符 P ,P
Pα
含有左递归的文法将使上述的自上而下的分析过程陷入无限循环,即当试图
用 P 去匹配输入串时,就会出现在没有吃进任何输入符号的情况下,又得重新要
求 P 去进行新的匹配。因此,使用自上而下分析法必须消除文法的左递归性。
对文法中一切左递归的消除要求文法中不含回路即无 A
A 的推导。满足这个要
求的充分条件是:文法中不包含形如 A→A 和 A→ε的空产生式。
根据消除左递归的算法步骤我们可以得出整个程序思路。对于产生式的存储问题,
采用定义产生式的结构体,再用表的形式来存储所有的产生式。再输入存储时就
将产生式的左部和右部分开存储于产生式结构体中,方便后面的操作。在消除左
递归的过程中,对于直接左递归,可将其改为直接右递归;对于间接左递归(也
称文法左递归),则应按照算法给出非终结符不同排列的等价的消除左递归后的
文法。