编译原理C语言LL1代码Word文档格式.docx
《编译原理C语言LL1代码Word文档格式.docx》由会员分享,可在线阅读,更多相关《编译原理C语言LL1代码Word文档格式.docx(31页珍藏版)》请在冰豆网上搜索。
/*用户输入时使用*/
charempt[20];
/*求_emp()时使用*/
charfo[20];
/*求FOLLOW集合时使用*/
/*******************************************
判断一个字符是否在指定字符串中
********************************************/
intin(charc,char*p)
{
inti;
if(strlen(p)==0)
return(0);
for(i=0;
;
i++)
{
if(p[i]==c)
return
(1);
/*若在,返回*/
if(i==strlen(p))
return(0);
/*若不在,返回*/
}
}
得到一个不是非终结符的符号
charc()
charc='
A'
while(in(c,non_ter)==1)
c++;
return(c);
分解含有左递归的产生式
voidrecur(char*point)
{/*完整的产生式在point[]中*/
intj,m=0,n=3,k;
chartemp[20],ch;
ch=c();
/*得到一个非终结符*/
k=strlen(non_ter);
non_ter[k]=ch;
non_ter[k+1]='
\0'
for(j=0;
j<
=strlen(point)-1;
j++)
if(point[n]==point[0])
{/*如果‘|’后的首符号和左部相同*/
for(j=n+1;
{
while(point[j]!
='
|'
&
point[j]!
)
temp[m++]=point[j++];
left[count]=ch;
memcpy(right[count],temp,m);
right[count][m]=ch;
right[count][m+1]='
m=0;
count++;
if(point[j]=='
{
n=j+1;
break;
}
}
}
else
{/*如果‘|’后的首符号和左部不同*/
left[count]=ch;
right[count][0]='
^'
right[count][1]='
count++;
for(j=n;
if(point[j]!
temp[m++]=point[j];
else
left[count]=point[0];
memcpy(right[count],temp,m);
right[count][m]=ch;
right[count][m+1]='
printf("
count=%d"
count);
m=0;
count++;
left[count]=point[0];
memcpy(right[count],temp,m);
right[count][m]=ch;
right[count][m+1]='
m=0;
分解不含有左递归的产生式
voidnon_re(char*point)
intm=0,j;
chartemp[20];
for(j=3;
{
if(point[j]!
temp[m++]=point[j];
{
right[count][m]='
left[count]=point[0];
memcpy(right[count],temp,m);
right[count][m]='
count++;
m=0;
读入一个文法
chargrammer(char*t,char*n,char*left,charright[50][50])
charvn[50],vt[50];
chars;
charp[50][50];
inti,j,k;
printf("
\n请输入文法的非终结符号串:
"
);
scanf("
%s"
vn);
getchar();
i=strlen(vn);
memcpy(n,vn,i);
n[i]='
请输入文法的终结符号串:
vt);
i=strlen(vt);
memcpy(t,vt,i);
t[i]='
请输入文法的开始符号:
%c"
&
s);
请输入文法产生式的条数:
%d"
i);
for(j=1;
=i;
printf("
请输入文法的第%d条(共%d条)产生式:
j,i);
scanf("
p[j-1]);
getchar();
=i-1;
if(p[j][1]!
-'
||p[j][2]!
>
'
{printf("
\ninputerror!
validity=0;
return('
}/*检测输入错误*/
for(k=0;
k<
k++)
{/*分解输入的各产生式*/
if(p[k][3]==p[k][0])
recur(p[k]);
non_re(p[k]);
return(s);
将单个符号或符号串并入另一符号串
voidmerge(char*d,char*s,inttype)
{/*d是目标符号串,s是源串,type=,源串中的‘^’一并并入目串;
type=,源串中的‘^’不并入目串*/
inti,j;
i<
=strlen(s)-1;
if(type==2&
s[i]=='
;
for(j=0;
if(j<
strlen(d)&
s[i]==d[j])
if(j==strlen(d))
d[j]=s[i];
d[j+1]='
求所有能直接推出^的符号
voidemp(charc)
{/*即求所有由‘^’推出的符号*/
chartemp[10];
=count-1;
if(right[i][0]==c&
strlen(right[i])==1)
temp[0]=left[i];
temp[1]='
merge(empty,temp,1);
emp(left[i]);
求某一符号能否推出‘^’
int_emp(charc)
{/*若能推出,返回;
否则,返回*/
inti,j,k,result=1,mark=0;
temp[0]=c;
temp[1]='
merge(empt,temp,1);
if(in(c,empty)==1)
return
(1);
if(i==count)
if(left[i]==c)/*找一个左部为c的产生式*/
j=strlen(right[i]);
/*j为右部的长度*/
if(j==1&
in(right[i][0],empty)==1)
return
(1);
elseif(j==1&
in(right[i][0],termin)==1)
return(0);
else
for(k=0;
=j-1;
if(in(right[i][k],empt)==1)
mark=1;
if(mark==1)
continue;
for(k=0;
{
result*=_emp(right[i][k]);
temp[0]=right[i][k];
temp[1]='
merge(empt,temp,1);
}
if(result==0&
count)
continue;
elseif(result==1&
判断读入的文法是否正确
intjudge()
if(in(left[i],non_ter)==0)
{/*若左部不在非终结符中,报错*/
printf("
\nerror1!
validity=0;
for(j=0;
=strlen(right[i])-1;
if(in(right[i][j],non_ter)==0&
in(right[i][j],termin)==0&
right[i][j]!
{/*若右部某一符号不在非终结符、终结符中且不为‘^’,报错*/
printf("
\nerror2!
validity=0;
return
(1);
求单个符号的FIRST
voidfirst2(inti)
{/*i为符号在所有输入符号中的序号*/
charc,temp[20];
intj,k,m;
c=v[i];
charch='
emp(ch);
if(in(c,termin)==1)/*若为终结符*/
first1[i][0]=c;
first1[i][1]='
}
elseif(in(c,non_ter)==1)/*若为非终结符*/
if(left[j]==c)
if(in(right[j][0],termin)==1||right[j][0]=='
temp[0]=right[j][0];
temp[1]='
merge(first1[i],temp,1);
elseif(in(right[j][0],non_ter)==1)
if(right[j][0]==c)
continue;
if(v[k]==right[j][0])
break;
if(f[k]=='
0'
{
first2(k);
f[k]='
1'
merge(first1[i],first1[k],2);
=strlen(right[j])-1;
empt[0]='
if(_emp(right[j][k])==1&
strlen(right[j])-1)
{
for(m=0;
m++)
if(v[m]==right[j][k+1])
break;
if(f[m]=='
{
first2(m);
f[m]='
}
merge(first1[i],first1[m],2);
}
elseif(_emp(right[j][k])==1&
k==strlen(right[j])-1)
temp[0]='
temp[1]='
merge(first1[i],temp,1);
else
f[i]='
求各产生式右部的FIRST
voidFIRST(inti,char*p)
intlength;
length=strlen(p);
if(length==1)/*如果右部为单个符号*/
if(p[0]=='
{
if(i>
=0)
first[i][0]='
first[i][1]='
else
TEMP[0]='
TEMP[1]='
if(v[j]==p[0])
memcpy(first[i],first1[j],strlen(first1[j]));
first[i][strlen(first1[j])]='
memcpy(TEMP,first1[j],strlen(first1[j]));
TEMP[strlen(first1[j])]='
else/*如果右部为符号串*/
if(v[j]==p[0])
break;
if(i>
merge(first[i],first1[j],2);
merge(TEMP,first1[j],2);
for(k=0;
=length-1;
empt[0]='
if(_emp(p[k])==1&
length-1)
{
for(m=0;
if(v[m]==right[i][k+1])
break;
if(i>
merge(first[i],first1[m],2);
merge(TEMP,first1[m],2);
elseif(_emp(p[k])==1&
k==length-1)
temp[0]='
temp[1]='
merge(first[i],temp,1);
merge(TEMP,temp,1);
elseif(_emp(p[k])==0)
求各产生式左部的FOLLOW
voidFOLLOW(inti)
intj,k,m,n,result=1;
c=non_ter[i];
/*c为待求的非终结符*/
merge(fo,temp,1);
if(c==start)
{/*若为开始符号*/
temp[0]='
#'
temp[1]='
merge(follow[i],temp,1);
if(in(c,right[j])==1)/*找一个右部含有c的产生式*/
for(k=0;
if(right[j][k]==c)
/*k为c在该产生式右部的序号*/
for(m=0;
if(v[m]==left[j])
/*m为产生式左部非终结符在所有符号中的序号*/
if(k==strlen(right[j])-1)
{/*如果c在产生式右部的最后*/
if(in(v[m],fo)==1)
merge(follow[i],follow[m],1);
if(F[m]=='
FOLLOW(m);
F[m]='
merge(follow[i],follow[m],1);
{/*如果c不在产生式右部的最后*/
for(n=k+1;
n<
n++)
{
empt[0]='
result*=_emp(right[j][n]);
if(result==1)
{/*如果右部c后面的符号串能推出^*/
if(in(v[m],fo)==1)
{/*避免循环递归*/
merge(follow[i],follow[m],1);