#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#define SIZE 128
char priority[6][6]; //算符优先关系表数组
char input[SIZE]; //存放输入的要进行分析的句子
char remain[SIZE]; //存放剩余串
char AnalyseStack[SIZE]; //分析栈
void analyse();
int testchar(char x); //判断字符X在算符优先关系表中的位置
void remainString(); //移进时处理剩余字符串,即去掉剩余字符串第一个字符
int k;
void init()//构造算符优先关系表,并将其存入数组中
{
priority[1][0]='>';
priority[1][1]='>';
priority[1][2]='<';
priority[1][3]='<';
priority[1][4]='>';
priority[1][5]='>';
priority[2][0]='>';
priority[2][1]='>';
priority[2][2]='$';//无优先关系的用$表示
priority[2][3]='$';
priority[2][4]='>';
priority[2][5]='>';
priority[3][0]='<';
priority[3][1]='<';
priority[3][2]='<';
priority[3][3]='<';
priority[3][4]='=';
priority[3][5]='$';
priority[4][0]='>';
priority[4][1]='>';
priority[4][2]='$';
priority[4][3]='$';
priority[4][4]='>';
priority[4][5]='>';
priority[5][0]='<';
priority[5][1]='<';
priority[5][2]='<';
priority[5][3]='<';
priority[5][4]='$';
priority[5][5]='=';
}
void analyse()//对所输入的句子进行算符优先分析过程的函数
{
int i,j,f,z,z1,n,n1,z2,n2;
int count=0;//操作的步骤数
char a; //用于存放正在分析的字符
char p,Q,p1,p2;
f=strlen(input); //测出数组的长度
for(i=0;i<=f;i++)
{
a=input[i];
if(i==0)
remainString();
if(AnalyseStack[k]=='+'||AnalyseStack[k]=='*'||AnalyseStack[k]=='i'
||AnalyseStack[k]=='('||AnalyseStack[k]==')'||AnalyseStack[k]=='#')
j=k;
else
j=k-1;
z=testchar(AnalyseStack[j]);//从优先关系表中查出s[j]和a的优先关系
if(a=='+'||a=='*'||a=='i'||a=='('||a==')'||a=='#')
n=testchar(a);
else //如果句子含有不是终结符集合里的其它字符,不合法
{
printf("错误!该句子不是该文法的合法句子!\n");
break;
}
p=priority[z][n];
if(p=='$')
{
printf("错误!该句子不是该文法的合法句子!\n");
return;
}
if(p=='>')
{ for( ; ; )
{
Q=AnalyseStack[j];
if(AnalyseStack[j-1]=='+'||AnalyseStack[j-1]=='*'||AnalyseStack[j-1]=='i'
||AnalyseStack[j-1]=='('||AnalyseStack[j-1]==')'||AnalyseStack[j-1]=='#')
j=j-1;
else
j=j-2;
z1=testchar(AnalyseStack[j]);
n1=testchar(Q);
p1=priority[z1][n1];
if(p1=='<') //把AnalyseStack[j+1]~AnalyseStack[k]归约为N
{
count++;
printf("(%d) %s\t%10c\t%5c%17s\t 归约\n",count,AnalyseStack,p,a,remain);
k=j+1;
i--;
AnalyseStack[k]='N';
int r,r1;
r=strlen(AnalyseStack);
for(r1=k+1;r1<r;r1++)
AnalyseStack[r1]='\0';
break;
}
else
continue;
}
}
else
{
if(p=='<') //表示移进
{
count++;
printf("(%d) %s\t%10c\t%5c%17s\t 移进\n",count,AnalyseStack,p,a,remain);
k=k+1;
AnalyseStack[k]=a;
remainString();
}
else
{
if(p=='=')
{
z2=testchar(AnalyseStack[j]);
n2=testchar('#');
p2=priority[z2][n2];
if(p2=='=')
{
count++;
printf("(%d) %s\t%10c\t%5c%17s\t 接受\n",count,AnalyseStack,p,a,remain);
printf("该句子是该文法的合法句子。\n");
break;
}
else
{
count++;
printf("(%d) %s\t%10c\t%5c%17s\t 移进\n",count,AnalyseStack,p,a,remain);
k=k+1;
AnalyseStack[k]=a;
remainString();
}
}
else
{
printf("错误!该句子不是该文法的合法句子!\n");
break;
}
}
}
}
}
int testchar(char x)
{
int m;
if(x=='+')
m=0;
if(x=='*')
m=1;
if(x=='i')
m=2;
if(x=='(')
m=3;
if(x==')')
m=4;
if(x=='#')
m=5;
return m;
}
void remainString()
{
int i,j;
i=strlen(remain);
for(j=0;j<i;j++)
remain[j]=remain[j+1];
remain[i-1]='\0';
}
int main()
{
init();
printf("请输入要进行分析的句子(以#号结束输入):\n");
gets(input);//将输入的字符串存到数组中
printf("步骤 栈 优先关系 当前符号 剩余输入串 移进或归约\n");
k=0;
AnalyseStack[k]='#';
AnalyseStack[k+1]='\0';
int length,i; //初始化剩余字符串数组为输入串
length=strlen(input);//
for(i=0;i<length;i++)
remain[i]=input[i];
remain[i]='\0';
analyse();//对所输入的句子进行算符优先分析过程的函数
return 0;
}