编译原理课程设计(词法语法分析器,follow集) 联系客服

发布时间 : 星期二 文章编译原理课程设计(词法语法分析器,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 -