#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 20
char warehouse[N];
char *nproduce="0";
char *forecast[5][8]={
"TH","0","0","0","0","TH","0","0", // 0表示没有产生式
"0","+TH","-TH","0","0","0","e","e", //e表示产生式为空产生式
"FP","0","0","0","0","FP","0","0",
"0","e","e","*FP","/FP","0","e","e",
"i","0","0","0","0","(E)","0","0"
}; //预测分析表
char ensymbol[8]={'i','+','-','*','/','(',')','#'}; //终结符
char nensymbol[5]={'E','H','T','P','F'}; //非终结符
void print()
{
printf("0 express no express grammar /n");
printf("the meaning of e is null /n");
printf("this is a forecast down /n");
printf("the produce type : /n");
printf("E-->TH /nH-->+TH|-TH|e /n");
printf("T-->FP /nP-->*FP|/FP|e /n");
printf("f-->i|(E) /n");
printf("nensymbol have: /n");
for(int i=0;i<5;i++)
printf("%c /t",nensymbol[i]);
printf("/nensymbol have: /n");
for(int j=0;j<8;j++)
printf("%c /t",ensymbol[j]);
printf("/nthe forecast is: /n");
for(int p=0;p<5;p++)
{
for(int q=0;q<8;q++)
printf("%s /t",forecast[p][q]);
printf("/n");
}
} //打印预测分析表的说明和解释
int strcmp(char s1[],char s2[])
{
int i=0;
if(s1[i]!='/0')
if(s1[i]==s2[i])
{
i++;
}
else
{
return(0);
}
else
{
if(s2[i]=='/0')
return(1);
else
return(0);
}
} //字符串的比较
void print1(char s1[],char s2[],int n)
{
int i=0;
for(i;i<=n;i++)
{
printf("%c",s1[i]);
}
printf("/t/t/t/t");
printf("%s",s2);
printf("/n");
} //打印表达式的推到过程
void main()
{
char s[N-1],X,a,ch;
int b,q,p;
int len;
b=q=p=0; //初始化
print(); //打印预测分析表
printf("please put the express you want to test:");
scanf("%s",s); //输入要分析的表达式
while(s[strlen(s)-1]!='#')
{
printf("please input string again.# is the end of string/n");
scanf("%s",s);
}
warehouse[q++]='#';
warehouse[q++]='E'; //栈的初始化
X=warehouse[--q];
a=*(s+p++);
while(1)
{
print1(warehouse,s+p-1,q);
for(int j=0;j<8;j++)
if(X==ensymbol[j]) //判读当前栈顶是不是终结符
{
b=1;
break;
}
if(b) //是终结符
{
if(X==a) //栈顶终结符是不是表达式要判读的终结符 是
{
if(X=='#') //判断终结符是不是结束符 是
{
if(X==a)
{
printf("success/n");
return; //该语句是该文法语句
}
}
else //不是终结符 把栈顶下移 和 表达式后移
{
a=*(s+p++);
X=warehouse[--q];
b=0;
}
}
else //栈顶表达式不是表达式要判断的终结符
{
printf("error/n");
exit(1); //不是该文法的语句
}
}
else //当前栈顶是非终结符
{
int i=j=0;
for(i;i<5;i++)
if(X==nensymbol[i]) //查找当前栈顶非终极符产生判断终结符数组下标
break;
for(j;j<8;j++)
if(a==ensymbol[j])
break;
if(j==8) //当前查找的字符不在终结符表里
{
printf("input is error .there is not a char in the ensymbol ./n");
exit(1);
}
else //在终结表里
{
int l;
if(strcmp(forecast[i][j],nproduce)) //是否有产生式 没有
{
printf("forecast[%d][%d] is not a express grammar/n",i,j);
exit(1);
}
else //有产生式
{
l=strlen(forecast[i][j])-1;
for(l;l>=0;l--)
{
if(*(forecast[i][j]+l)=='e')
break;
else
warehouse[q++]=*(forecast[i][j]+l);
} //把数字的产生式放入栈中
X=warehouse[--q]; //去出栈顶元素
}
}
}
}
}
如何修改使之更小