算符优先分析方法

#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;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值