算符优先分析方法

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



算符优先分析法 C++ 编译原理 运行环境:Visual Studio 2005 #include "SStack.h" #include <iostream> #include <string> using namespace std; class Functor { private : char ** table; string ** production; string prog;//待分析字符串 int p;//字符指针 int num;//终结符个数 int num1;//产生式个数 SStack <char> stack; public: Functor(int m,int n,char ** T,string **prod,string pr) { num=m; num1=n; table=T; production=prod; prog=pr; p=0; stack.push('$'); } void traversal() { while(p<(prog.length())) { stack.display(); cout<<prog.substr(p)<<" "; char ch; if(Getnum(stack.gettop())) { ch=stack.gettop(); } else { ch=stack.getsecond(); } switch(compare(ch,prog[p])) { case 1: case 2:stack.push(prog[p]);p++;cout<<"移入"<<endl;break; case 3:reduct();cout<<"归约"<<endl;break; } } cout<<"分析成功!"<<endl; } int Getnum(char ch) { for(int i=1;i<num;i++) { if(ch==table[i][0]) { return i; } } return 0; } int compare(char col,char row) { int c=Getnum(col); int r=Getnum(row); switch( table[c][r]) { case '>': return 3;break; case '<': return 2;break; case '=': return 1;break; default:cout<<endl<<"输入串有误,程序将终止!"<<endl;system("pause");exit(0);break; } } void reduct() { //待定 string token=""; int temp; string str=""; if(!Getnum(stack.gettop())) { token+=stack.gettop(); stack.pop(); } char ch=stack.gettop(); str+=ch; temp=Haven(str); if(temp!=-1) { token+=production[temp][0]; } else { token+=ch; } stack.pop(); bool Nover=true; while(Nover) { if(Getnum(stack.gettop())) { if(compare(stack.gettop(),ch)==2) { Nover=false; } else { ch=stack.gettop(); str=""; str+=ch; temp=Haven(str); if(temp!=-1) { token+=production[temp][0]; } else { token+=ch; } stack.pop(); } } else { token+=stack.gettop(); stack.pop(); } } string token2=""; //cout<<token<<" "; for(int i=token.length()-1;i>=0;i--) { token2+=token[i]; } //cout<<token2<<endl; if(Haven(token2)!= -1) { stack.push(production[Haven(token2)][0][0]); } else { cout<<"输入串有误!分析终止!"<<endl; system("pause"); exit(0); } } int Haven(string temp) { for(int i=0;i<num1;i++) { int j=1; while(production[i][j]!="") { if(temp==production[i][j]) { return i; } j++; } } return -1; } public: ~Functor(void) { } };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值