G2
E->E+T | E-T | T
T->T*F | T/F |F
F->(E) | n
n->0 | 1 |2 |… |9
注意扫描是从右向左扫描,第一次的展开其实得到的是最后一个符号。
如果遇到+或-,则将表达式中的E变为E+T或E-T;
如果遇到*或/,则将表达式中的T变成T*F或T/F;
如果遇到括号对,则将表达式中的F变成(E);
如果没有符号,只有数字,则将表达式中的E变成T,T变成F,F变成n,n变成相应数字
遍历完一次之后,以符号为分割线,将表达式分割成两部分进行下一次扫描
持续递归,直到中间表达式中没有字母,只剩数字和符号
#include <stdio.h>
#include <string.h>
void Generate(char *s,int L,int n,char P);
int step=1;
int main()
{
char LIST[1024];
int N;
printf("请输入所需推导的式子:\n");
scanf("%s",LIST);
N=strlen(LIST);
Generate(LIST,0,N-1,'E');
printf("最左推导此式共需%d步",step-1);
printf("\nEND\n");
return 0;
}
void Generate(char *s,int L,int n,char P)
{
int i,flag=0,t=0;
if(P=='E')
{
for(i=n;i>=L;--i) // 必须要从右往左扫描字符串
{
if(s[i]==')')
t++;
else if(s[i]=='(')
t--;
if(t) continue;
if(s[i]=='+'||s[i]=='-')
{
printf("第%d步: E->E%cT\n",step,s[i]);
step++;
Generate(s,L,i-1,'E');
Generate(s,i+1,n,'T');
flag=1;
break;
}
}
if(!flag)
{
printf("第%d步: E->T\n",step);
step++;
Generate(s,L,n,'T');
}
}
else if(P=='T')
{
for(i=n;i>=L;--i)
{
if(s[i]==')')
t++;
else if(s[i]=='(')
t--;
if(t) continue;
if(s[i]=='*'||s[i]=='/')
{
printf("第%d步: T->T%cF\n",step,s[i]);
step++;
Generate(s,L,i-1,'T');
Generate(s,i+1,n,'F');
flag=1;
break;
}
}
if(!flag)
{
printf("第%d步: T->F\n",step);
step++;
Generate(s,L,n,'F');
}
}
else if(P=='F')
{
if(s[L]=='(')
{
printf("第%d步: F->(E)\n",step);
step++;
Generate(s,L+1,n-1,'E');
}
else
{
printf("第%d步: F->n\n",step);
step++;
printf("第%d步: n->%c\n",step,s[L]);
step++;
}
}
}