发布时间 : 星期二 文章编译原理课程设计(词法语法分析器,follow集)更新完毕开始阅读b6863ceeaeaad1f346933f50
if(i==Pcount)
return(0);
if(leftStr[i]==c) //找一个左部为c的产生式 {
j=strlen(rightStr[i]); //j为c所在产生式右部的长度
if(j==1&&FindChar(rightStr[i][0],epsilon))//右部长度为1且右部第一个字符在epsilon[]
中.返回1(A->B,B可推出空)
return(1);
else if(j==1&&FindChar(rightStr[i][0],terSymbol))//右部长度为1但第一个字符为终结符,
返回0(A->a,a为终结符)
return(0);
else {
for(k=0;k<=j-1;k++)
if(FindChar(rightStr[i][k],tempEpsilon))//tempEpsilon[].(A->AB)
mark=1;
查
找
临
时
数
组
if(mark==1)//找到的字符与当前字符相同(A->AB)
continue;//结束本次循环
else//(mark等于0)
{
for(k=0;k<=j-1;k++) {
result*=someDerivateEpsilon(rightStr[i][k]);//查找右部符号是否可推出
空字,把返回值赋给result
里.
}
}
}
temp[0]=rightStr[i][k]; temp[1]='\\0';
join(tempEpsilon,temp,true);//把当前符号加入到临时数组tempEpsilon[]
- 15 -
条产生式
} }
if(result==0&&i //如果当前字符不能推出空字且还没搜索完全部的产生式,则跳出本次循环继续搜索下一 continue; else if(result==1&&i return(1); /************************************************** 求各产生式左部(非终结符)的FOLLOW集 求得结果保存在followSET中 参数i为该符号在非终结符中的位置 算法: (1)对于文法开始符号S,则#∈FOLLOW(S); (2)若A→αBβ,其中B∈VN,α∈(VT U VN)*、β∈(VT UVN)+,则FIRST(β)-{ε}∈FOLLOW(B); (3)若A→αB或A→αBβ(β=>*ε),则FOLLOW(A)∈FOLLOW(B)。 /**************************************************/ void FOLLOW(int i) { int j,k,m,n,result=1; char X,temp[20]; X=non_ter[i]; //X为待求的非终结符 temp[0]=X; temp[1]='\\0'; //把当前字符放到一临时数组tempFOLLOW[]中,标识求已求其FOLLOW集.避免循环递归 join(tempFOLLOW,temp,false); //若为开始符号-----开始符号S,则#∈FOLLOW(S) if(X==startSymbol) { temp[0]='#'; - 16 - } temp[1]='\\0'; join(followSET[i],temp,false); //把#号加入到当前字符的FOLLOW集 //若A→αB或A→αBβ for(j=0;j<=Pcount-1;j++) { 产生式 for(k=0;;k++) if(rightStr[j][k]==X) break; //k为X在该产生式右部的序号.如B在产生式A→αB中的位置 if(FindChar(X,rightStr[j])) //找一个右部含有当前字符X的产生式 { //比如求FOLLOW(B)则找A→αB或A→αBβ(β=>*ε)的 for(m=0;;m++) if(allSymbol[m]==leftStr[j]) break; //m为产生式左部非终结符在所有符号中的序号 //如果X在产生式右部的最后,形如产生式A→αB,则FOLLOW(A)∈FOLLOW(B) if(k==(int)strlen(rightStr[j])-1) { if(FindChar(allSymbol[m],tempFOLLOW)) //查找该非终结符是否已经求过其 FOLLOW集.避免循环递归 如下 join(followSET[i],followSET[m],false); //把X所在产生式的左部非终结符 { //是则FOLLOW(A)∈FOLLOW(B), 的FOLLOW集加入到FOLLOW(X)中 continue; //结束本次循环,进入j++循环 } if(followed[m]=='0') { } join(followSET[i],followSET[m],false); //FOLLOW(A)∈FOLLOW(B) FOLLOW(m); //求之FOLLOW集 //如果该非终结符的FOLLOW未求过 followed[m]='1'; //标识为1 - 17 - } else//如果X不在产生式右部的最后,形如A→αBβ { for(n=k+1;n<=(int)strlen(rightStr[j])-1;n++) { tempEpsilon[0]='\\0'; //把tempEpsilon[]置空, //因为求此字符是否可推出空字 someDerivateEpsilon(c)时用到 } if(result==1)//如果右部X后面的符号串能推出@---A→αBβ(β=>*ε)则 result*=someDerivateEpsilon(rightStr[j][n]); FOLLOW(A)∈FOLLOW(B) { if(FindChar(allSymbol[m],tempFOLLOW))//查找该非终结符是否已经求过其FOLLOW集.避免循环递归 } followed[i]='1';//标识当前要求的非终结符的FOLLOW集已求过 } } if(followed[m]=='0') { FOLLOW(m); followed[m]='1'; } { } join(followSET[i],followSET[m],false);//FOLLOW(A)∈FOLLOW(B) continue; //结束本次循环 join(followSET[i],followSET[m],false);//FOLLOW(A)∈FOLLOW(B) } - 18 -