第二部分,這一部分用來記錄各類函數、變量,以及根據標籤得到函數、變量的一系列函數,以及反過來根據值得到標籤的一系列函數(這是爲了方便輸出、檢測錯誤)。 數組
由於我已經有好用的解析器了,這個就不打算用多好的方法了,只是簡單的數組記錄和查找。實際上是用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; }