⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expressioncompli.cpp

📁 一个C++对赋值语句的翻译,能输出四元式
💻 CPP
字号:
/*  Class CExpression CPP
/   By Great_csk 2004
/
/
*/

#include "ExpressionCompli.h"
#include ".\expressioncompli.h"
#include <cstdio>
#define SAFE_DELETE(p) ((p==0)?0:delete p)
CExpression::CExpression() : nScanPos(0)
{
    t_expression =new char[MAX_EXP]; 
	n_last_error=ERROR_NULL;
	num_table="0123456789.";
	operator_table="+-*/()# ^";
}

CExpression::~CExpression(){

   ClearStack();
   delete[] t_expression;
}

hResult CExpression::Compile(){
	//
	if (n_last_error!=ERROR_NULL) return n_last_error;
	int prev_operator,cur_operator;
	long tresult;
	EXP_ITEM *tmpItem;	
	prev_operator=' ';
	ClearStack();
	
	pexpItem=new EXP_ITEM;
	while(tresult=GetNextStrItem(pexpItem)){
		
		if (pexpItem->item_type==ITEM_TYPE_OPERATOR){
			cur_operator=pexpItem->itemdata.operator_data;
          
			if (tresult=operatorToStack(prev_operator,cur_operator)!=ERROR_NULL){
				SAFE_DELETE( pexpItem);
				return tresult;
			}
			tmpItem=(EXP_ITEM *)stkItems.getTop();
			if (tmpItem==0){
				SAFE_DELETE( pexpItem);
				n_last_error=ERROR_STACK_ERROR;

				return ERROR_STACK_ERROR;
			}
			prev_operator=tmpItem->itemdata.operator_data;

		}else
		{
			printf("%g,",pexpItem->itemdata.num_data);
			stkExp.AddNode((void *)pexpItem);
			
		}
		pexpItem=new EXP_ITEM;
	}
	ClearStack(STACK_ITEM);
	if (n_last_error==ERROR_COMPLINE) {
	
		return ERROR_COMPLINE;
	}
	return ERROR_NULL;
}


hResult CExpression::Solve(double &result){
	EXP_ITEM *num1,*num2;
	EXP_ITEM *tmpItem;
	double tmpData;
	num2=num1=NULL;
	if (n_last_error!=ERROR_NULL) return n_last_error;
	ClearStack(STACK_ITEM);

	stkExp.GotoFirst();

  

	do{
		pexpItem=(EXP_ITEM *)stkExp.ReadNode();
		if (pexpItem==0){
			ClearStack(STACK_ITEM);
			return n_last_error=ERROR_EXP_END;
		}
		
		switch(pexpItem->item_type){
				case ITEM_TYPE_OPERATOR:
					//Is Operator
					num2=(EXP_ITEM *)stkItems.pop();
					num1=(EXP_ITEM *)stkItems.pop();

					if (num1==0 || num2==0){
						SAFE_DELETE(num1);
						SAFE_DELETE(num2);
						ClearStack(STACK_ITEM);
						n_last_error=ERROR_STACK_ERROR;
						return n_last_error;
					}
					if (num1->item_type!=ITEM_TYPE_NUM || num2->item_type!=ITEM_TYPE_NUM){
						SAFE_DELETE(num1);
						SAFE_DELETE(num2);						
						n_last_error=ERROR_BAD_USEAGE;
						ClearStack(STACK_ITEM);
						return n_last_error;
					}
					tmpData=CalculateValueByOperator(num1->itemdata.num_data,num2->itemdata.num_data,pexpItem->itemdata.operator_data);
					if (n_last_error!=ERROR_NULL) {
						SAFE_DELETE(num1);
						SAFE_DELETE(num2);
						ClearStack(STACK_ITEM);
						return n_last_error;
					}
					num1->itemdata.num_data=tmpData;
					stkItems.push((pData)num1);
					delete num2;
					break;
				case ITEM_TYPE_NUM:
					//Is Num
					tmpItem=new EXP_ITEM;
					*tmpItem=*pexpItem;
					stkItems.push((pData)tmpItem);					
					break;
		}

	}while(stkExp.GotoNext());

	pexpItem=(EXP_ITEM *)stkItems.pop();
	if (pexpItem){
		if (pexpItem->item_type==ITEM_TYPE_NUM){
			result=pexpItem->itemdata.num_data;
			n_last_error=ERROR_NULL;
		}else
		{
			n_last_error=ERROR_BAD_USEAGE;
		}
	}else
	{
		n_last_error=ERROR_STACK_ERROR;
	}
	SAFE_DELETE( pexpItem );
	ClearStack(STACK_ITEM);
	return n_last_error;


}


hResult CExpression::SetExpression(pExpression exp){
	int i,j;
	char holder;
	
	n_last_error=ERROR_NULL;
	t_expression[0]='#';
	ClearStack();
	j=1;i=0;
	while(exp[i]){
		holder=exp[i];
		if (holder=='(' && GetDataType(t_expression[j-1])==ITEM_TYPE_NUM){
			t_expression[j]='*';
			j++;
		}
		t_expression[j]=holder;
		i++;
		j++;
	}
	t_expression[j]='#';
	t_expression[j+1]='\0';

	nScanPos=0;



	return 0;
}

long CExpression::GetNextStrItem(EXP_ITEM * pItem)
{
	char CurrentType,PrevType;
	char CurrentChar;

	int OrgPos;

	PrevType=CurrentType=ITEM_TYPE_NULL;

	CurrentChar=*(t_expression+nScanPos);

	OrgPos=nScanPos;

	while(CurrentChar){

		CurrentType=GetDataType(CurrentChar);
		nScanPos++;

		if (CurrentType==ITEM_TYPE_OPERATOR){

			if (CurrentChar=='-' || CurrentChar=='+'){     //-a?

				if ( GetDataType(*(t_expression+nScanPos)) == ITEM_TYPE_OPERATOR ){
					pItem->item_type=ITEM_TYPE_OPERATOR;
					pItem->itemdata.operator_data=CurrentChar;
					return true;					
				}else
				{
					pItem->item_type=ITEM_TYPE_OPERATOR;
					pItem->itemdata.operator_data=CurrentChar;
					return true;
				}
			}
			else{

				pItem->item_type=ITEM_TYPE_OPERATOR;
				pItem->itemdata.operator_data=CurrentChar;
				return true;
			}

		}


		if (CurrentType==ITEM_TYPE_NUM && GetDataType(*(t_expression+nScanPos))==ITEM_TYPE_OPERATOR && *(t_expression+nScanPos-2)!=')'){
			pItem->item_type=ITEM_TYPE_NUM;
			if (StrToFloat(t_expression,OrgPos,nScanPos-1,&pItem->itemdata.num_data)!=COMPLINE_SUCCEED) 
			{
				n_last_error=ERROR_COMPLINE;
				return false;
			}

			return true;	
		}

		if (CurrentType==ITEM_TYPE_NULL){
				n_last_error=ERROR_COMPLINE;
				return false;
		}
		CurrentChar=*(t_expression+nScanPos);

		PrevType=CurrentType;

	}

	n_last_error=ERROR_EXP_END;
	return false;
}

char CExpression::GetDataType(char t_char)
{
	if (IsInTheTable(num_table,t_char)) return ITEM_TYPE_NUM;
	if (IsInTheTable(operator_table,t_char)) return ITEM_TYPE_OPERATOR;
	return ITEM_TYPE_NULL;
}

bool CExpression::IsInTheTable(char * pTable,char QueryChar)
{
	int scanpoint=0;
	char scanchar;
	scanchar=*(pTable+scanpoint);
	while(scanchar){

		if (scanchar==QueryChar) return true;
		scanpoint++;
		scanchar=*(pTable+scanpoint);
	}

	return false;
}

int CExpression::StrToFloat(pExpression pExp, int start, int end, double* ans)
{
	int scanPos;
	bool IsNeg,//<0?
		 Isfloat;
	char CurrentChar;
	int floatpoint;
	scanPos=start;
	IsNeg=false;
	Isfloat=false;
	*ans=0;

	if (pExp[start]=='-' || pExp[start]=='+'){
		scanPos++;

		IsNeg=(pExp[start]=='-');
	}
	for (;scanPos<=end;scanPos++){
		CurrentChar=pExp[scanPos];
		if (CurrentChar=='.'){
			if (Isfloat) return COMPLINE_BAD_TYPE; //more than one '.'
			floatpoint=scanPos;
			Isfloat=true; //is float num
		
		}
		else{
			if (CurrentChar>='0' && CurrentChar<='9'){


				*ans*=10;
				*ans+=CurrentChar-'0';

			}else{
				//return COMPLINE_BAD_TYPE;
			}
		}

	}

	if (Isfloat==true){
		for (int i=0;i<scanPos-floatpoint-1;i++){
			(*ans)/=10;
		}
      
	}
	if (IsNeg) *ans=-(*ans);
	return COMPLINE_SUCCEED;
}

bool CExpression::ClearStack(int nType)
{
	if (nType==STACK_ALL || nType==STACK_EXP){
		stkExp.GotoEnd();
		while(pexpItem=(EXP_ITEM *)stkExp.ReadNode()){
			SAFE_DELETE( pexpItem);
			stkExp.DeleteNode();
		}
	}
	if (nType==STACK_ALL || nType==STACK_ITEM){
		while(pexpItem=(EXP_ITEM *)stkItems.pop()){
			SAFE_DELETE( pexpItem);
		}
	}
	return false;
}

int CExpression::OperatorComp(char operator1, char operator2)
{
	char op_ID_1,op_ID_2;
	char i;
	/*
	    + - * / ( ) # 0 ^
	-------------------------------
	+   > > < < < > > N <
	-   > > < < < > > N <
	*   > > > > < > > N <
	/   > > > > < > > N <
	(   < < < < < = N N <
	)   > > > > N > > N >
	#   < < < < < = < > <
	0   N N N N N N < N N
	^   > > > > < > > N >
	*/
	int operator_level[9][9]={   
		1, 1,-1,-1,-1, 1, 1, 'N',-1,
		1, 1,-1,-1,-1, 1, 1, 'N',-1,
		1, 1, 1, 1,-1, 1, 1, 'N',-1,
		1, 1, 1, 1,-1, 1, 1, 'N',-1,
		-1,-1,-1,-1,-1, 0,'N','N',-1,
		1, 1, 1, 1,'N',1, 1, 'N', 1,
		-1,-1,-1,-1,-1, 'N', 0,  1 ,-1,
		'N','N','N','N','N','N', -1,'N','N',
		1, 1, 1, 1,-1, 1, 1,'N',1
	};
	for (i=0;i<9;i++){
		if (operator_table[i]==operator1) op_ID_1=i;
		if (operator_table[i]==operator2) op_ID_2=i;
	}

	return operator_level[op_ID_1][op_ID_2];
}

int CExpression::operatorToStack(char operator1, char operator2)
{

	EXP_ITEM *tmpItem;		


	switch(OperatorComp(operator1,operator2)){

				

				case 0:  // ==
					if (operator1=='(' && operator2==')'){
						tmpItem= (EXP_ITEM *)stkItems.pop();

						if (tmpItem==0){
							n_last_error=ERROR_STACK_ERROR;
							return ERROR_STACK_ERROR;
						}
						delete tmpItem;
					}
					break;
				case 1:  // >

					tmpItem=(EXP_ITEM *)stkItems.pop();

					if (tmpItem==0){
						n_last_error=ERROR_STACK_ERROR;
						return ERROR_STACK_ERROR;
					}
					printf("<%c>",tmpItem->itemdata.operator_data);
						
					stkExp.AddNode((void *)tmpItem);
			
					
					tmpItem=(EXP_ITEM *)stkItems.getTop();
					if (tmpItem==0){
						n_last_error=ERROR_STACK_ERROR;
						return ERROR_STACK_ERROR;
					}
					return operatorToStack(tmpItem->itemdata.operator_data,operator2);


					break;

				case -1: // <
					
					if (stkItems.push((pData)pexpItem)==0){
						 n_last_error=ERROR_STACK_OVERFLOW;
						 return ERROR_STACK_OVERFLOW;
					}

					break;

				case 'N':// N/A
					n_last_error=ERROR_BAD_USEAGE;
					return ERROR_BAD_USEAGE;
					break;



	}
	return ERROR_NULL;
}

double CExpression::CalculateValueByOperator(double num1, double num2, char Operator)
{
	n_last_error=ERROR_NULL;
	switch(Operator){
		case '+':
			return num1+num2;
			break;
		case '-':
			return num1-num2;
			break;
		case '*':
			return num1*num2;
			break;
		case '/':
			if (num2){
				return num1/num2;
			}else
			{
				n_last_error=ERROR_DIVIDED_BY_ZERO;
			}
			break;
		case '^':
			break;

	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -