📄 编译原理-算符优先.c
字号:
#include <stdio.h>
void find_firstvt();
struct expression
{ char vn;
char vright[15];
}expr[15];
struct exp_first
{
char name;
char value[15] ;
} ;
int tablenum=0;
char vn[15];
char vt[10*15];
char rightvn[15];
char rightvnlast[15];
struct exp_first cando[15];
struct exp_first candolast[15];
int num;
struct exp_first vnname[15];
struct exp_first lastvt[15]; //
void last();
void table();
int mysign=0;
int sign2=0;
int sign3=0;
int mysign1=0;
int sign4=0;
int sign5=0;
char fuhaotable[15][15];
char newvt[15];
main()
{
int k;
int i;
char a[10];
int s;
int sign=0;
int biaoji=0;
int t=0;
int v=0;
int j;
printf("*******************************说明*******************************\n");
printf("注意!!!!本文法不支持一式含有多个产生式,例如:S->A|b|c\n请输入时将其分解成三个表达式:S->A ; S->b; S->c\n");
printf("同时,要求输入产生式时,先输入产生式左部,回车后再输入产生式右部 \n");
printf("*******************************************************************\n");
printf("请输入你的产生式条数:" );
scanf("%d",&num);
for(i=0;i<num;i++)
{
printf("请输入第%d个产生式的[左部],然后回车:\n",i+1);
scanf("%s",&expr[i].vn);
printf(" ->");
printf("[右部]",i+1);
scanf("%s",expr[i].vright);
}
//存非终结符
for(i=0;i<num;i++)
{
if(expr[i].vn>64&expr[i].vn<91)
vn[i]=expr[i].vn;
else { printf("error");
exit(0);}
}
for(i=0;i<num;i++)
{for(j=0;j<num;j++)
{ if((vn[i] ==vn[j] )&&(i<j))
vn[j]=0;
}}
//存终结符 以及右部非终结符
for(i=0;i<num;i++)
{
for(j=0;j<10;j++)
{
for(s=0;s<num;s++)
{
if((vn[s]==expr[i].vright[j])&&(vn[s]!=NULL)&&(expr[i].vright[j]!=NULL))
{biaoji=1;
//rightvn
rightvn[v]=expr[i].vright[j];
rightvnlast[v]=expr[i].vright[j];
v++;}
}
if(biaoji==0)
{
if(t==0)
{
vt[t]=expr[i].vright[j];
t++;
}
else
{
for(k=0;k<t;k++)
{
if((vt[k]==expr[i].vright[j]))
{sign=1; }
}
if(sign==0)
{ vt[t]=expr[i].vright[j];
t++;
}
sign=0;
}
}
biaoji=0;
} }
find_firstvt(); //输出文法的终结符集,非终结符集
xiaolian(); //求各非终结符的FIRSTVT集
last(); //求各非终结符的LASTVT集
table(); //判定文法是否为算符优先文法,如是,则输出构造出的算符优先关系表
}
void find_firstvt() //输出文法的终结符集,非终结符集
{
int i,j;
printf(" *********************本文法中终结符为:***********************************\n");
for(i=0;i<15;i++)
{
if(vt[i]!=0) {
newvt[tablenum]=vt[i];
tablenum+=1;
printf(" %c,",vt[i]);
}
}
printf(" \n");
printf("********* ****************本文法中的非终结符为:**************************\n");
for(i=0;i<15;i++)
{
if(vn[i]!=0)
printf(" %c ,",vn[i]);
}
printf(" \n");
}//最后的括号
xiaolian( ) //求各非终结符的FIRSTVT集
{
int i,j,k,sign=0,v,a,h,c=0;
int r;
//kaishi
for(i=0;i<num;i++)
{
vnname[i].name=expr[i].vn;
//求出第一个是终结符的表达式的
for(k=0;k<15;k++)
{
if(expr[i].vright[0]==vt[k])
{
vnname[i].value[0] =vt[k];
} // 求出第一个是终结符的表达式的,结束
if ((expr[i].vright[0]==vn[k])&&(expr[i].vright[1]!=0) )
{
vnname[i].value[0] =expr[i].vright[1];
} //qiu第二个是终结符的
if((expr[i].vright[0]==vn[k])&&(expr[i].vright[1]==0))
{
vnname[i].value[0] =vn[k];
} // qiu 右部只有一个非终结符的
} } // for的括号
k=1;
for(i=0;i<num;i++)
{
for(j=0;j<num;j++)
{
if((vnname[i].name==vnname[j].name)&&(i!=j))
{ vnname[i].value[k]=vnname[j].value[0];
k++;
}
}
}
//唯一化
for(i=0;i<num;i++)
{for(j=0;j<num;j++)
{ if((vnname[i].name==vnname[j].name)&&(i<j))
vnname[j].name=0;
}}
//rightvn's
for(i=0;i<num;i++)
{for(j=0;j<num;j++)
{ if((rightvn[i]==rightvn[j] )&&(i<j))
rightvn[j]=0;
}}
//将右部的非终结符转化为终结符
AA:
sign3=0;
for(i=0;i<num;i++) {
for(j=0;j<num;j++)
{
if((vnname[i].name==rightvn[j])&&(rightvn[j]!=0))
{
for(k=0;k<15;k++){
for(v=0;v<num;v++){
if((vnname[i].value[k]==vn[v])&&(vn[v]!=0))
{mysign=1; } } }
if(mysign==0)
{cando[c].name=vnname[i].name;
for(a=0;a<num;a++)
{if(vnname[i].value[a]!=0)
{cando[c].value[a]=vnname[i].value[a];
}}
r=c;
c++;}
for(h=0;h<num;h++){
if((rightvn[h]==cando[r].name)&&(rightvn[h]!=0))
rightvn[h]=0;}
mysign=0; }}
}
for(i=0;i<num;i++){
for(j=0;j<15;j++)
{ for(k=0;k<num;k++){
if((vnname[i].value[j]==cando[k].name)&&(cando[k].name!=0))
{ sign2=1;
}
if(sign2==1){
for(a=0;a<15;a++){
if (cando[k].value[a]!=0) {
for(h=0;h<15;h++) {
if((vnname[i].value[h]==cando[k].name)||(vnname[i].value[h]==0))
{vnname[i].value[h]=cando[k].value[a];
break;}} } }
}
sign2=0;
}} }
for(h=0;h<num;h++){
if(rightvn[h]!=0)
sign3=1;}
if(sign3==1) goto AA;
//将firstvt唯一化
for(i=0;i<num;i++)
{for(j=0;j<num;j++)
for(k=0;k<15;k++){
{ if((vnname[i].value[j]==vnname[i].value[k])&&(j<k))
vnname[i].value[k]=0;
}} }
//output
printf("**************************输出firstvt:********************\n");
for(i=0;i<num;i++)
{if(vnname[i].name!=0){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -