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

我幾年前初學C++的時候,曾經花了很長時間實現了表達式的解析和運算,支持函數和變量,還能夠進行求導等操做,是我比較得意的成果,如今一翻看,卻以爲滿頭霧水,大概是當初沒有註釋的習慣,又習慣於把大段大段的代碼都塞在一個函數裏吧。 數組

此次決定從新進行一次實現,算是複習一下語法,也會使用一些最近才掌握的技巧。 函數

這個文件用來聲明所需的各類數據類型,我採用虛函數來實現運算,也就是說數值和變量也有求值運算。能夠看到我用了聯合來節省空間。 code

不打算使用後綴表達式數組來計算,而使用二叉樹,二叉樹的好處是,若是須要能夠方便的實現懶惰求值、求導。固然這個就不打算這麼作了,只是複習麼。 get

/*
0	1	2	3	4	5	6	7	8	9
左括號	逗號	右括號	數值	變量	函數1p	函數2p	算符1p	算符2p	賦值符
*/

typedef double  *Addrs;
typedef double (*Fun1p)(double);
typedef double (*Fun2p)(double,double);

enum AtomType{Is_Empty,Is_Lquot,Is_Comma,Is_Rquot,Is_Value,Is_Param,Is_Fun1p,Is_Fun2p,Is_Opr1p,Is_Opr2p,Is_Setvr};

struct myFac
{
	union
	{
		char opr[8];
		double *adr;
		double  vlu;
		Fun1p   fc1;
		Fun2p   fc2;
	};
	virtual double get()
	{
		return 0;
	}
	virtual double run(double x)
	{
		return 0 && x;
	}
	virtual double run(double x,double y)
	{
		return 0 && x && y;
	}
	virtual double set(double &x,double y)
	{
		return 0 && x && y;
	}
};
struct myValue:myFac
{
	virtual double get()
	{
		return vlu;
	}
};
struct myParam:myFac
{
	virtual double get()
	{
		return *adr;
	}
};
struct myOpr1p:myFac
{
	virtual double run(double x)
	{
		switch(opr[0])
		{
			case '+':return x;
			case '-':return -x;
			case '!':return x?0:1;
			case '#':return x?1:0;
			case '$':return x<0?-x:x;
			case '@':return x<0?-1:x>0?1:0;
		}
		return 0;
	}
};
struct myFun1p:myFac
{
	virtual double run(double x)
	{
		return fc1(x);
	}
};
struct myOpr2p:myFac
{
	virtual double run(double x,double y)
	{
		switch(opr[0])
		{
			case '+':return x+y;
			case '-':return x-y;
			case '*':return x*y;
			case '/':return x/y;
			case '=':return x==y;
			case '!':return x!=y;
			case '&':return (bool)x && (bool)y;
			case '|':return (bool)x || (bool)y;
			case '>':return (opr[1]=='=')?(x>=y):(x>y);
			case '<':return (opr[1]=='=')?(x<=y):(x<y);
		}
		return 0;
	}
};
struct myFun2p:myFac
{
	virtual double run(double x,double y)
	{
		return fc2(x,y);
	}
};
struct mySetvr:myFac
{
	virtual double set(double x,double y)
	{
		switch(opr[0])
		{
			case '=':x=y;break;
			case '+':x+=y;break;
			case '-':x-=y;break;
			case '*':x*=y;break;
			case '/':x/=y;break;
		}
		return x;
	}
};
struct Atom
{
	AtomType type;
	myFac   *data;
	Atom    *Lsun;
	Atom    *Rsun;
	Atom()
	{
		type=Is_Empty;
		data=NULL;
		Lsun=NULL;
		Rsun=NULL;
	}
	~Atom()
	{
		if(data)delete data;
	}
};
void Remove(Atom *(&root))
{
	if(root)
	{
		Remove(root->Lsun);
		Remove(root->Rsun);
		delete root;
		root=NULL;
	}
}
struct Lequ
{
	Atom *equ;
	Lequ *lst;
	Lequ *nxt;
	Lequ()
	{
		equ=NULL;
		lst=NULL;
		nxt=NULL;
	}
	~Lequ()
	{
		if(equ)Remove(equ);
	}
};
void Remove(Lequ *(&root))
{
	Lequ *sp,*md;
	sp=root;
	while(sp)
	{
		md=sp->nxt;
		delete sp;
		sp=md;
	}
}
相關文章
相關標籤/搜索