文法是E->TA、A->+TA|-TA|ε、T->FB、B->*FB|/FB|ε、F->(E)|i ,可以判断输入的表达式是否正确,且能指出错误的原因,并能生成简单的语法分析树。
源程序为
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char out='o';
char str[50]={0};
char arr[50][100]={0};
int inter=0;
int len;
char n=0;
char m;
int number=1;
int row=0;
int col=0;
int timeA=0;
int timeB=0;
int timeT=0;
int timeE=1;//由E开始
void E();
void A();
void T();
void B();
void F();
void num(){
printf("%d\t",number);
number++;
}
void residue(){
for(int i=inter;i<=len;i++){
printf("%c",str[i]);
}
printf("\n");
}
void E(){//E->TA
num();
printf("E->TA\t\t");
residue();
if(timeE>=2){
row=row+2;
arr[row][col-1]='/';
arr[row][col+1]='\\';
arr[row+1][col-4]='T';
arr[row+1][col+3]='A';
row++;col=col-4;
}
timeT++;
T();
timeA++;
if(timeT>1){
row=row-3;//要根据图调整
col=col+5;
}
else{
row=2;
col=36;
}
A();
}
void A(){//A->+TA|-TA|ε
if(str[inter]=='+'){
num();
printf("A->+TA\t\t");
residue();
inter++;
row++;
arr[row][col-2]='/';
arr[row][col]='|';
arr[row][col+2]='\\';
arr[row+1][col-3]='+';
arr[row+1][col]='T';
arr[row+1][col+5]='A';
row++;
timeT++;
T();
timeA++;
row=row-3;//根据图调整
col=col+3;
A();
}else if(str[inter]=='-'){
num();
printf("A->-TA\t\t");
residue();
inter++;
row++;
col++;
n=str[inter];
m=str[inter+1];
arr[row][col-1]='/';
arr[row][col]='|';
arr[row][col+2]='\\';
arr[row+1][col-2]='-';
arr[row+1][col]='T';
arr[row+1][col+5]='A';
str[inter]=n;
str[inter+1]=m;
row++;
timeT++;
T();
timeA++;
row=row-3;//根据图调整
col=col+5;
A();
}
else {
num();
printf("A->ε\t\t");
residue();
row++;
}
}
void T(){//T->FB
num();
printf("T->FB\t\t");
residue();
if(timeT>1){
row++;
arr[row][col-2]='/';
arr[row][col+1]='\\';
arr[row+1][col-3]='F';
arr[row+1][col+2]='B';
row++;col=col-3;
}
F();
timeB++;
col=col+4;row--;//根据图调整
B();
}
void B(){//B->*FB|/FB|ε
if(str[inter]=='*'){
num();
printf("B->*FB\t\t");
residue();
inter++;
row++;
arr[row][col-2]='/';
arr[row][col]='|';
arr[row][col+2]='\\';
arr[row+1][col-3]='*';
arr[row+1][col]='F';
arr[row+1][col+3]='B';
row++;
F();
timeB++;
row=row-1;//根据图调整
col=col+4;
B();
}else if(str[inter]=='/'){
num();
printf("B->/FB\t\t");
residue();
inter++;
row++;
arr[row][col-2]='/';
arr[row][col]='|';
arr[row][col+2]='\\';
arr[row+1][col-3]='/';
arr[row+1][col]='F';
arr[row+1][col+3]='B';
row++;
F();
timeB++;
row=row-0;//根据图调整
col=col+4;
B();
}
else{
num();
printf("B->ε\t\t");
residue();
row++;
}
}
void F(){//F->(E)|i
if(str[inter]=='('){
num();
printf("F->(E)\t\t");
residue();
inter++;
row++;
arr[row][col-1]='/';
arr[row][col]='|';
arr[row][col+1]='\\';
arr[row+1][col-2]='(';
arr[row+1][col]='E';
arr[row+1][col+2]=')';
timeE++;
E();
if(str[inter]==')'){
num();
printf("F->(E)\t\t");
residue();
inter++;
}
else{
printf("表达式分析结果:该表达式语法错误\n");
printf("表达式错误原因:表达式中缺少')'");
exit(0);//错误则退出
}
}else if(str[inter]=='i'||str[inter]<='9'&&str[inter]>='0'||str[inter]<='z'&&str[inter]>='a'){
num();
printf("F->i\t\t");
residue();
inter++;
row++;
arr[row][col]='|';
arr[row+1][col]='i';
}else if(str[inter]==')'){
printf("表达式分析结果:该表达式语法错误\n");
printf("表达式错误原因:表达式中缺少'('");
exit(0);
}else{
printf("表达式分析结果:该表达式语法错误\n");
printf("表达式错误原因:表达式中缺少或者不是数字或标识符");
exit(0);
}
}
int main(){
while(1){
for(int i=0;i<50;i++){
str[i]=0;
}
for(int i=0;i<50;i++){
for(int j=0;j<100;j++){
arr[i][j]=0;
}
}
number=1;n=0;inter=0;row=0,col=0;
timeA=0;timeB=0;timeT=0;timeE=1;//由E开始
arr[0][30]='E';
arr[1][25]='/';//表示父节点和子节点的从属关系
arr[1][35]='\\';//注意'\'是转义字符
arr[2][24]='T';
arr[2][36]='A';
arr[3][23]='/';
arr[3][25]='\\';
arr[4][22]='F';
row=4;col=22;
arr[4][26]='B';
printf("请输入表达式:");
scanf("%s", str);
len = strlen(str);
str[len] = '#';
if(str[0]=='#'){
printf("'#'为结束标志,不能作为输入\n");
printf("请重新输入!");
exit(0);
}
printf("步骤\t 文法\t\t 剩余串\n");
E();
if (str[inter] == '#'){
printf("表达式分析结果:该表达式语法正确\n");
printf("该表达式的语法分析树为:\n");
}
else if(str[inter]==')'){
printf("表达式分析结果:该表达式语法错误\n");
printf("表达式错误原因:表达式中缺少'('\n");
exit(0);
}else{
printf("表达式分析结果:该表达式语法错误\n");
printf("表达式错误原因:不是合法的句子\n");
exit(0);
}
for(int i=0;i<30;i++){//打印语法分析树
for(int j=0;j<50;j++)
{
printf("%c",arr[i][j]);
}
printf("\n");
}
printf("输入'q'退出,输入'c'继续:");
scanf("%s",&out);
printf("\n");
if(out=='q'){
exit(0);
}
}
return 0;
}
运行结果为
1.表达式正确的为:
2.表达式错误: