#include "stdio.h"
#include "string.h"
#define MaxSize 20
char prog[80],token[6];
char ch;
int syn,p,m,n,sum;
char *rwtab[6] = {"begin","if","then","while","do","end"};
typedef struct
{
int top;
char stack[MaxSize];
}operatorStack;
operatorStack stack1;
typedef struct
{
int top;
float stack[MaxSize];
}operandStack;
operandStack stack2;
void push_operatorStack(char ch)
{
stack1.stack[++stack1.top] = ch;
}
char pop_operatorStack()
{
return stack1.stack[stack1.top--];
}
char top_operatorStack()
{
return stack1.stack[stack1.top];
}
void push_operandStack(float ch)
{
stack2.stack[++stack2.top] = ch;
}
float pop_operandStack()
{
return stack2.stack[stack2.top--];
}
float top_operandStack()
{
return stack2.stack[stack2.top];
}
int f(char ch)
{
switch(ch)
{
case '*':return 5;break;
case '/':return 5;break;
case '+':return 3;break;
case '-':return 3;break;
case '$':return 0;break;
default :return -1;break;
}
}
int g(char ch)
{
switch(ch)
{
case '*':return 4;break;
case '/':return 4;break;
case '+':return 2;break;
case '-':return 2;break;
case '$':return 0;break;
default :return -1;break;
}
}
void scaner()
{
for(int i = 0; i < 8; i++)
token[i] = NULL;
m = 0;
ch= prog[p++];
while(ch == ' '){ch = prog[p++];}
if((ch >= 'a' && ch <= 'z')||(ch >= 'A' && ch <= 'Z'))
{
while((ch >= 'a' && ch <= 'z')||(ch >= 'A' && ch <= 'Z')||(ch >= '0' && ch <='9' ))
{
token[m++] = ch;
ch = prog[p++];
}
token[m++] = '\0';
ch = prog[--p];
syn = 10; //syn=10表示标识符
for(n = 0; n < 6; n++)
if(strcmp(token,rwtab[n]) == 0)//判断token数组与rwtab[n]关键字数组是否相等
{
syn = n + 1; //若相等,则置syn为对应的关键字的种别码值
break;
}
}
else if(ch <= '9' && ch >= '0')
{
sum = 0;
while(ch <= '9' && ch >= '0')
{
sum = sum * 10 + ch - '0';
ch = prog[p++];
}
ch = prog[--p];
syn = 11; //syn=11表示数字
}
else{
switch(ch)
{
case '<':m = 0;token[m++] = ch;
ch = prog[p++];
if(ch == '>')
{
syn = 21;
token[m++] = ch;
}
else if(ch == '=')
{
syn = 22;
token[m++] = ch;
}
else
{
syn = 20;
ch = prog[--p];
}
break;
case '>':m = 0;token[m++] = ch;
ch = prog[p++];
if(ch == '=')
{
syn = 24;
token[m++] = ch;
}
else
{
syn = 23;
ch = prog[--p];
}
break;
case ':':m = 0;token[m++] = ch;
ch = prog[p++];
if(ch == '=')
{
syn = 18;
token[m++] = ch;
}
else
{
syn = 17;
ch = prog[--p];
}
break;
case '+':syn = 13;token[0] = ch;break;
case '-':syn = 14;token[0] = ch;break;
case '*':syn = 15;token[0] = ch;break;
case '/':syn = 16;token[0] = ch;break;
case ':=':syn = 18;token[0] = ch;break;
case '<>':syn = 21;token[0] = ch;break;
case '<=':syn = 22;token[0] = ch;break;
case '>=':syn = 24;token[0] = ch;break;
case '=':syn = 25;token[0] = ch;break;
case ';':syn = 26;token[0] = ch;break;
case '(':syn = 27;token[0] = ch;break;
case ')':syn = 28;token[0] = ch;break;
case '#':syn = 0;token[0] = ch;break;
case '$':syn = 100;token[0] = ch;break;
default:syn = -1;
}
}
}
void middle(char ch)
{
float result;
float operand2 = pop_operandStack();
float operand1 = pop_operandStack();
char temp = pop_operatorStack();
switch(ch)
{
case'+':result = operand1 + operand2;
push_operandStack(result);
break;
case'-':result = operand1 - operand2;
push_operandStack(result);
break;
case'*':result = operand1 * operand2;
push_operandStack(result);
break;
case'/':result = operand1 / operand2;
push_operandStack(result);
break;
default :break;
}
//printf("%.0f = %.0f %c %.0f\n",result,operand1,ch,operand2);
}
int compare(char ch)
{
if(f(top_operatorStack()) < g(ch) || f(top_operatorStack()) == g(ch))
{
push_operatorStack(ch);
}
else if(f(top_operatorStack()) > g(ch))
{
while(top_operatorStack() != '$' || ch != '$')
{
if(f(top_operatorStack()) < g(ch) || f(top_operatorStack()) == g(ch))
{
push_operatorStack(ch);
return 0;
}
else if(f(top_operatorStack()) > g(ch))
{
middle(top_operatorStack());
}
}
}
return 0;
}
int main()
{
p = 0;
/*
printf("Please input string:\n");
do
{
scanf("%c",&ch);
prog[p++] = ch;
}while(ch != '#');
*/
FILE *fp= fopen("file1.txt","r");
fread(prog,sizeof(char),80,fp);
fclose(fp);
p = 0;
stack1.top = -1;
push_operatorStack('$');
stack2.top = -1;
scaner();
while(syn != 0)
{
if(syn == 11) //如果是数字,入操作数栈
{push_operandStack((float)sum);scaner();}
else if(syn == 15) //如果是*
{compare(token[0]);scaner();}
else if(syn == 16) //如果是/
{compare(token[0]);scaner();}
else if(syn == 13) //如果是+
{compare(token[0]);scaner();}
else if(syn == 14) //如果是-
{compare(token[0]);scaner();}
else if(syn == 100) //如果是$
{compare(token[0]);scaner();}
else{scaner();}
}
//printf("%c,%c,%.0f\n",ch,top_operatorStack(),top_operandStack());
printf("%.0f\n",top_operandStack());
return 0;
}
算符优先分析方法
最新推荐文章于 2023-05-24 18:49:24 发布