從頭開始搭建算術表達式解析器,第二部分

第二部分,這一部分用來記錄各類函數、變量,以及根據標籤得到函數、變量的一系列函數,以及反過來根據值得到標籤的一系列函數(這是爲了方便輸出、檢測錯誤)。 數組

由於我已經有好用的解析器了,這個就不打算用多好的方法了,只是簡單的數組記錄和查找。實際上是用AVL樹、hash表或者紅黑樹都更好一點,也方便加入新的函數與變量。 函數


namespace _Temp_Cequ
{

	double __Int(double x){return (long)x;}
	double __Rnd(double x){return (x>0)?(long)x+(x-(long)x>=0.5):(long)x-((long)x-x>=0.5);}
	double __Cot(double x){return 1/tan(x);}
	double _Acot(double x){return atan(1/x);}
	double __Ang(double x,double y){return ((x*y<0)+(y<0))*atan(y/x);}
	double __Log(double x,double y){return log(y)/log(x);}
	double _Rand(double x){return rand()*x/32768;}
	
	template<typename T>
	struct Relate
	{
		char Sign[8];
		T    Lead;
	};

	Relate<short>  Oper[21]={{"=",1},{"+=",1},{"-=",1},{"*=",1},{"/=",1},{"&&",2},{"||",2},{">",3},{"<",3},{">=",3},{"<=",3},{"==",3},{"!=",3},{"+",4},{"-",4},{"*",5},{"/",5},{"!",6},{"#",6},{"@",6},{"$",6}};
	Relate<Fun1p>  Fun1[14]={{"acos",acos},{"acot",_Acot},{"asin",asin},{"atan",atan},{"exp",exp},{"int",__Int},{"lg",log10},{"ln",log},{"cos",cos},{"cot",__Cot},{"rand",_Rand},{"round",__Rnd},{"sin",sin},{"tan",tan}};
	Relate<Fun2p>  Fun2[ 3]={{"pow",pow},{"angle",__Ang},{"log",__Log}};
	Relate<double> Vars[26]={{"a",0},{"b",0},{"c",0},{"d",0},{"e",0},{"f",0},{"g",0},{"h",0},{"i",0},{"j",0},{"k",0},{"l",0},{"m",0},{"n",0},{"o",0},{"p",0},{"q",0},{"r",0},{"s",0},{"t",0},{"u",0},{"v",0},{"w",0},{"x",0},{"y",0},{"z",0}};

}
Addrs GetParam(char *str)
{
	int n=26;
	while(n)
	{
		if(strcmp(str,_Temp_Cequ::Vars[--n].Sign)==0)
		{
			return &(_Temp_Cequ::Vars[n].Lead);
		}
	}
	return NULL;
}
Fun1p GetFun1p(char *str)
{
	int n=14;
	while(n)
	{
		if(strcmp(str,_Temp_Cequ::Fun1[--n].Sign)==0)
		{
			return _Temp_Cequ::Fun1[n].Lead;
		}
	}
	return NULL;
}
Fun2p GetFun2p(char *str)
{
	int n=3;
	while(n)
	{
		if(strcmp(str,_Temp_Cequ::Fun2[--n].Sign)==0)
		{
			return _Temp_Cequ::Fun2[n].Lead;
		}
	}
	return NULL;
}
short GetOpert(char *str)
{
	int n=21;
	while(n)
	{
		if(strcmp(str,_Temp_Cequ::Oper[--n].Sign)==0)
		{
			return _Temp_Cequ::Oper[n].Lead;
		}
	}
	return 0;
}
short GetRight(Atom *p)
{
	if(p)
	{
		switch(p->type)
		{
			case Is_Opr1p:return 6;
			case Is_Fun1p:return 6;
			case Is_Fun2p:return 6;
			case Is_Opr2p:return GetOpert(p->data->opr);
			case Is_Setvr:return 1;
			default:return 0;
		}
	}
	return 0;
}
char *GetParamLabel(Addrs adr)
{
	int n=26;
	while(n)
	{
		if(adr==&(_Temp_Cequ::Vars[--n].Lead))
		{
			return _Temp_Cequ::Vars[n].Sign;
		}
	}
	return NULL;
}
char *GetFun1pLabel(Fun1p adr)
{
	int n=14;
	while(n)
	{
		if(adr==_Temp_Cequ::Fun1[--n].Lead)
		{
			return _Temp_Cequ::Fun1[n].Sign;
		}
	}
	return NULL;
}
char *GetFun2pLabel(Fun2p adr)
{
	int n=3;
	while(n)
	{
		if(adr==_Temp_Cequ::Fun2[--n].Lead)
		{
			return _Temp_Cequ::Fun2[n].Sign;
		}
	}
	return NULL;
}
相關文章
相關標籤/搜索