名称:用SLR(1)分析技术对输入串进行句型分析
输入:SLR(1)分析表(保存为text.txt文件)、分析的句型
文件示例:
实现代码如下:
(每个函数的功能在代码中均有注释)
#include<stdio.h>
#include<string.h>
typedef struct any_W //保存文法
{
char unset;
char wenFA[8];
}W;
typedef struct any_table //保存分析表
{
char body[8];
}table;
int step_NUM=0;
int calculate(char a[]) //计算带字母的状态
{
int i;
int num=0;
for(i=1;i<=strlen(a)&&a[i]!='\0';i++)
{
num=num*10+(a[i]-'0'); //注意字符与整形的转换
}
return num;
}
int calculate_INT(char a[]) //计算不带字母的状态
{
int i;
int num=0;
for(i=0;a[i]!='\0';i++)
{
num=num*10+(a[i]-'0');
}
return num;
}
int print_K(char a[]) //规范格式输出空格
{
int k;
for(k=15;k>strlen(a);k--)
printf(" ");
return 0;
}
int print_K_INT(int num)
{
int k;
for(k=16;k>num;k--) //输出格式控制
{
printf(" ");
}
return 0;
}
void clear_W(W a[]) //初始化文法保存数组wen
{
for(int i=0;i<20;i++)
{
a[i].unset='\0';
for(int k=0;k<8;k++)
a[i].wenFA[k]='\0';
}
}
void ana_C(table a[][50]) //初始化二维表
{
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
for(int k=0;k<sizeof(a[i][j].body);k++)
a[i][j].body[k]='\0';
}
}
}
void clear(char a[]) //清空字符串数组
{
int i=strlen(a);
for(int k=0;k<i;k++)
a[k]='\0';
}
void clear_INT(int a[]) //清空int型数组
{
for(int k=0;k<sizeof(a);k++)
a[k]=-1;
}
int table_NUM(char n,char t[]) //查找元素n在一维数组中的位置
{
int num=0;
for(;num<strlen(t);num++)
{
if(n==t[num])
return num;
}
return -1;
}
int sourch(char a[],char x) //查找相同元素,找到返回1,未找到返回0
{
int i=0;
for(;i<strlen(a);i++)
{
if(a[i]==x)
return 1;
}
return 0;
}
void input_SET(char fiset[],table ana[][50],W wen[]) //输入分析表(文件读入)
{
int hr;
int w_NUM=1;
int fiset_NUM=0;
char fiset_S;
int i=0;
int q=0;
int p;
FILE *fp=NULL;
fp=fopen("text.txt","r");
char x[20];
clear(x);
while(!feof(fp))
{
fscanf(fp,"%s",x);
if(x[0]=='$')break;
q++;
if(q%2==1)
{
wen[w_NUM].unset=x[0];
clear(x);
}
if(q%2==0)
{
strcpy(wen[w_NUM].wenFA,x);
clear(x);
w_NUM++;
}
}
clear(x);
while(!feof(fp))
{
i++;
if(i%3==1)
{
fscanf(fp,"%d",&p);
hr=p+1;
clear(x);
}
if(i%3==2)
{
fscanf(fp,"%s",x);
fiset_S=x[0];
if(sourch(fiset,fiset_S)==0) //为找到终结符
{
fiset[fiset_NUM++]=x[0];
fiset[fiset_NUM]='\0';
}
clear(x);
}
if(i%3==0)
{
fscanf(fp,"%s",x);
int lr=table_NUM(fiset_S,fiset);
strcpy(ana[hr][lr].body,x);
ana[hr][lr].body[strlen(x)]='\0';
fiset_S='\0';
clear(x);
}
}
fclose(fp);
}
void input_HAND(char fiset[],table ana[][50]) //添加表头
{
int i,j;
for(i=0;i<strlen(fiset);i++)
{
ana[0][i].body[0]=fiset[i];
ana[0][i].body[1]='\0';
}
}
void output_ANA(table analysis[][50],char fiset_T[]) //分析表的输出
{
int i,j,k;
for(i=0;i<=12;i++)
{
if(i!=0)
printf("%2d ",i-1);
else
printf(" ");
for(j=0;j<=strlen(fiset_T);j++)
{
if(fiset_T[j]<'A'||fiset_T[j]>'Z')
{
if(analysis[i][j].body[0]!='\0')
printf("%6s",analysis[i][j].body);
else
printf(" -");
}
}
for(j=0;j<=strlen(fiset_T);j++)
{
if(fiset_T[j]>='A'&&fiset_T[j]<='Z')
{
if(analysis[i][j].body[0]!='\0')
printf("%6s",analysis[i][j].body);
else
printf(" -");
}
}
printf("\n");
}
}
void output_PRO(int ana_ZT[],char ana_FH[],char ana_V,char value[],int zt_NUM,int fh_NUM,int v_NUM,int behaver,int lr,char fiset[],table analysis[][50],int flag,char q_S,int back_NUM)
//过程的输出
{
int qq=1;
int w=0;
int k;
printf("%2d ",step_NUM);
for(int k=0;k<=zt_NUM;k++)
printf("%d",ana_ZT[k]);
for(int q=0;q<=zt_NUM;q++)
{
if(ana_ZT[q]>10)
{
w=zt_NUM+qq;
qq++;
}
else w=zt_NUM;
}
print_K_INT(w);
for(int k=0;k<=fh_NUM;k++)
printf("%c",ana_FH[k]);
print_K(ana_FH);
printf("%c ",ana_V);
for(int k=v_NUM;k<strlen(value);k++)
printf("%c",value[k]);
for(k=0;k<6+v_NUM;k++)
{
printf(" ");
}
printf("ACTION[%2d,%c]=%3s ",ana_ZT[zt_NUM],ana_V,analysis[behaver+1][lr].body);
step_NUM++;
}
//查找 goto语句的B
char sourch_FH_back(int A,char C,char fiset[],table analysis[][50])//goto(A,B)=C
{
int i;
for(i=0;i<strlen(fiset);i++)
{
if(analysis[A+1][i].body[0]==C)
break;
}
return fiset[i];
}
void error()
{
printf("输入句子不符合文法规则\n");
}
int ana_FUNCTION_ANA(table analysis[][50],char fiset[],W wen[],char value[])
{
int back_NUM;
char q_S;
int c;
int p;
char v;
int flag_P=0; //0为无goto, 1为有goto
int lr;
int ana_ZT[50]; //状态栈
char ana_FH[50]; //符号栈
clear_INT(ana_ZT);
clear(ana_FH);
int behaver; //当前状态
char x;
int zt_NUM=0;
int fh_NUM=0;
int v_NUM=0;
ana_ZT[zt_NUM]=0; //栈初始化
ana_FH[fh_NUM]='#';
char ana_V;
ana_V=value[v_NUM];
behaver=ana_ZT[zt_NUM];
lr=table_NUM(ana_V,fiset);
output_PRO(ana_ZT,ana_FH,ana_V,value,zt_NUM,fh_NUM,v_NUM+1,behaver,lr,fiset,analysis,flag_P,q_S,back_NUM);
printf(" <移入>");
printf("\n");
p=calculate(analysis[behaver+1][lr].body);
ana_ZT[++zt_NUM]=p;
ana_FH[++fh_NUM]=value[v_NUM];
ana_FH[fh_NUM+1]='\0';
v_NUM++;
while(1)
{
ana_V=value[v_NUM]; //当前输入符
behaver=ana_ZT[zt_NUM]; //当前状态
lr=table_NUM(ana_V,fiset); //当前输入符号的列
if(analysis[behaver+1][lr].body[0]=='s')
{
flag_P=0;
output_PRO(ana_ZT,ana_FH,ana_V,value,zt_NUM,fh_NUM,v_NUM+1,behaver,lr,fiset,analysis,flag_P,q_S,back_NUM);
p=calculate(analysis[behaver+1][lr].body);
ana_ZT[++zt_NUM]=p; //加入状态
ana_FH[++fh_NUM]=ana_V;
ana_FH[fh_NUM+1]='\0';
v_NUM++;
printf(" <移入>");
printf("\n");
}
else
{
if(analysis[behaver+1][lr].body[0]=='r')
{
output_PRO(ana_ZT,ana_FH,ana_V,value,zt_NUM,fh_NUM,v_NUM+1,behaver,lr,fiset,analysis,flag_P,q_S,back_NUM);
int p=calculate(analysis[behaver+1][lr].body); //r后面的状态
back_NUM=strlen(wen[p].wenFA); //r后的状态所对应的文法的右边长度
zt_NUM-=back_NUM;
fh_NUM-=back_NUM;
c=ana_ZT[zt_NUM]; //回退后的状态
q_S=wen[p].unset; //文法的左边
int lr_S=table_NUM(q_S,fiset); //文法左边对应的下标
int back_T=calculate_INT(analysis[c+1][lr_S].body); //新的状态
ana_ZT[++zt_NUM]=back_T;
ana_FH[++fh_NUM]=wen[p].unset;
ana_FH[fh_NUM+1]='\0';
printf(" GOTO[%2d,%c]=%2d",c,q_S,back_T);
printf(" <归约>\n");
}
else
{
if(behaver==1)
{
output_PRO(ana_ZT,ana_FH,ana_V,value,zt_NUM,fh_NUM,v_NUM+1,behaver,lr,fiset,analysis,flag_P,q_S,back_NUM);
printf(" <接受>");
printf("\nCONGRATRULATION!\n");
break;
}
else
{
error();
break;
}
}
}
}
return 0;
}
int main()
{
printf("状态 ACTION GOTO\n");
W wen[20];
clear_W(wen); //初始化文法表
table analysis[50][50]; //定义分析表
ana_C(analysis);
char fiset_T[20]; //符号数组
clear(fiset_T);
input_SET(fiset_T,analysis,wen);
input_HAND(fiset_T,analysis);
output_ANA(analysis,fiset_T);
printf("请输入需要分析的字符串,以#结尾\n");
char value_A[50];
clear(value_A);
scanf("%s",value_A);
value_A[strlen(value_A)]='\0';
printf("步骤 状态栈 符号栈 当前输入符 剩余输入串 ACTION GOTO 当前操作\n");
ana_FUNCTION_ANA(analysis,fiset_T,wen,value_A);
return 0;
}