这是一个能识别加法和乘法的语法分析器,例如在提示输入后输入一个算式:3+5*2*(2+1)这类的,那么就会给出匹配过程,并判断是不是成功,请赏析!由于构造了first集,follow集,select集之类,所以比较占篇幅,惭愧!
#include<string.h>
int isterminal(char a)
{if((a=='i')||(a=='+')||(a=='*')||(a=='(')||(a==')')||(a=='$'))
return(1);
else return(0);
}
int notin(char a,char *b)
{char *c;
for(c=b;(*c)!='\0';c++)
{if((*c)==a) break;
}
if((*c)=='\0') return(1);
else return(0);
}
void add(char *g,char *q,char *a)
{char *tem;
tem=a;
for(;(*tem)!='\0';tem++)
{if(notin((*tem),g))
{(*q)=(*tem);
q++;
(*q)='\0';
}
}
}
int maybenull(char E)
{char product[8][5]={"SBA","A+BA","A","BDC","C*DC","C","D(S)","Di"};
int i;
for(i=0;i<8;i++)
{if((product[i][0]==E)&&(product[i][1]=='\0'))
break;
}
if(i<8) return(1);
else if(i>=8) return(0);
}
char *first(char E)
{char product[8][5]={"SBA","A+BA","A","BDC","C*DC","C","D(S)","Di"};
char group[200],*q;
int i,j;
q=group;
if(isterminal(E))
{(*q)=E;
q++;
(*q)='\0';
}
else
{for(i=0;i<8;i++)
{if(product[i][0]==E)
{if(isterminal(product[i][1])&¬in(product[i][1],group))
{(*q)=product[i][1];
q++;
(*q)='\0';
}
else if((!isterminal(product[i][1]))&&((product[i][1])!='\0'))
{add(group,q,first(product[i][1]));
for(j=1;j<(strlen(product[i]));j++)
{if(maybenull(product[i][j])&&(product[i][j+1]!='\0'))
add(group,q,first(product[i][j+1]));
}
}
}
}
}
return(group);
}
char *follow(char E)
{char product[8][5]={"SBA","A+BA","A","BDC","C*DC","C","D(S)","Di"};
char group[200],*q,*tem;
int i,j,k;
q=group;
if(E=='S')
{(*q)='$';
q++;
(*q)='\0';
}
for(i=0;i<8;i++)
{for(j=1;j<strlen(product[i]);j++) /*startfor1*/
{if(product[i][j]==E) /*startif*/
{if(isterminal(product[i][j+1])) /*startif1*/
{(*q)=product[i][j+1];
q++;
(*q)='\0';
} /*endif1*/
else if(!isterminal(product[i][j+1])) /*startif2*/
{if(product[i][j+1]=='\0') /*startif3*/
{if(product[i][0]!=E)
add(group,q,follow(product[i][0]));
} /*startif3*/
else if(product[i][j+1]!='\0') /*startif4*/
{tem=first(product[i][j+1]);
for(;(*tem)!='\0';tem++)
{if(notin((*tem),group))
{(*q)=(*tem);
q++;
(*q)='\0';
}
}
for(k=j+1;k<(strlen(product[i])-1);k++) /*startfor2*/
{if(maybenull(product[i][k]))
{add(group,q,first(product[i][k+1]));
}
else break;
} /*endfor2*/
if(k==(strlen(product[i])-1))add(group,q,follow(product[i][k]));
} /*endif4*/
} /*endif2*/
} /*endif*/
} /*endfor1*/
}
return(group);
}
char *select(int n)
{char product[8][5]={"SBA","A+BA","A","BDC","C*DC","C","D(S)","Di"};
char group[200],*q;
int i=1,j=0;
q=group;
if(product[n][i]!='\0')
{add(group,q,first(product[n][1]));
for(j=i;j<(strlen(product[n]));j++)
{if(maybenull(product[n][j]))
{if(product[n][j+1]!='\0')
add(group,q,first(product[n][j+1]));
else if(product[n][j+1]=='\0') add(group,q,follow(product[n][0]));
}
else break;
}
}
else if(product[n][1]=='\0') add(group,q,follow(product[n][0]));
return(group);
}
void print(char *a)
{char *b=a;
if(strlen(a)==1)printf("%c->null",*b);
else
{printf("%c->",*b);
for(b++;(*b)!='\0';b++)printf("%c",*b);
}
}
main()
{char product[8][5]={"SBA","A+BA","A","BDC","C*DC","C","D(S)","Di"};
char s[200],*p,sentence[40][7],type[40],stack[15]="$S";
int count=0,i,j,k=0;
printf("Please write in the string you want to analysis:\n");
gets(s);
p=s;
while((*p)!='\0') /*while1*/
{if(((*p)=='+')||((*p)=='*')||((*p)=='(')||((*p)==')'))
{sentence[count][0]=(*p);
type[count]=(*p);
type[count+1]='$';
type[count+2]='\0';
sentence[count][1]='\0';
p++;
count++;
}
else if((*p)>='0'&&(*p)<='9')
{for(i=0;(*p)>='0'&&(*p)<='9';i++)
{sentence[count][i]=(*p);
p++;
}
sentence[count][i]='\0';
type[count]='i';
type[count+1]='$';
type[count+2]='\0';
count++;
}
else
{printf("Fail to analyse!");
break;
}
} /*endwhile1*/
sentence[count][0]='$';
sentence[count][1]='\0';
count++;
printf("The process of analysis is below:\n\n");
printf("Stack\t\t\tInput String\t\tOutput\n\n");
printf("%s\t\t\t%s$\n",stack,s);
p=type;
while((*p)!='\0')
{if(stack[strlen(stack)-1]=='$')break;
if(!isterminal(stack[strlen(stack)-1]))
{for(i=0;i<8;i++)
{if((product[i][0]==stack[strlen(stack)-1])&&(!(notin((*p),select(i)))))
{stack[strlen(stack)-1]='\0';
if(strlen(product[i])>1)
{for(j=strlen(product[i])-1;j>=1;j--)
stack[strlen(stack)]=product[i][j];
}
printf("%s\t\t\t",stack);
for(j=k;j<count;j++)printf("%s",sentence[j]);
printf("\t\t\t");
print(product[i]);
printf("\n");
break;
}
else continue;
}
if(i>=8)
{printf("\nError analysis!");
break;
}
}
else if(isterminal(stack[strlen(stack)-1]))
{if(stack[strlen(stack)-1]==(*p))
{stack[strlen(stack)-1]='\0';
p++;
printf("%s\t\t\t",stack);
for(j=k;j<count;j++)printf("%s",sentence[j]);
printf("\n");
k++;
}
else printf("Error analysis!");
}
}
if(((*p)=='$')&&stack[strlen(stack)-1]=='$')
printf("Analyse Successfully!");
getch();
}
评论