專利名稱:用于復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的構(gòu)件化實(shí)現(xiàn)的制作方法
技術(shù)領(lǐng)域:
本發(fā)明屬于電信運(yùn)營(yíng)商大規(guī)模準(zhǔn)確數(shù)據(jù)處理應(yīng)用技術(shù),尤其是電信運(yùn)營(yíng)中用于復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的構(gòu)件化實(shí)現(xiàn)。
背景技術(shù):
隨著通信業(yè)務(wù)的不斷迅速發(fā)展,各電信運(yùn)營(yíng)商推出更多更復(fù)雜的業(yè)務(wù),并且原有業(yè)務(wù)規(guī)則也在不斷變化,電信業(yè)務(wù)的發(fā)展對(duì)軟件設(shè)計(jì)和編碼提出的更高要求,然而即使使用多種設(shè)計(jì)模式,也難以適應(yīng)電信業(yè)務(wù)不斷發(fā)展的需求,迫切需要系統(tǒng)有一種通用編碼方式,來(lái)適應(yīng)業(yè)務(wù)的變化和擴(kuò)展。
目前的電信計(jì)費(fèi)系統(tǒng)在對(duì)增加和修改業(yè)務(wù)時(shí),沒(méi)有一種統(tǒng)一的解決辦法,很多時(shí)刻是采用硬編碼的方式解決,當(dāng)一種業(yè)務(wù)發(fā)生變化或產(chǎn)生一種新的業(yè)務(wù)時(shí),往往是找到業(yè)務(wù)相對(duì)應(yīng)的代碼進(jìn)行修改,也有部分業(yè)務(wù)會(huì)采用配置解決的方式,但配置放置的地點(diǎn)各不相同,有把配置放在數(shù)據(jù)庫(kù)中,有放置在文件中,不同的業(yè)務(wù)有不同的配置文件,不同配置方式,沒(méi)有固定統(tǒng)一的格式。
電信業(yè)務(wù)系統(tǒng)版本會(huì)應(yīng)用于許多省份,不同的省份有不同的業(yè)務(wù),按傳統(tǒng)的方法要對(duì)不同的業(yè)務(wù)進(jìn)行編碼形成業(yè)務(wù)模塊,在需要的省份進(jìn)行增減,不同的省份對(duì)相同的業(yè)務(wù)也可能要求有不同的處理方式,按傳統(tǒng)的方案,要為不同的省份做一個(gè)版本,在實(shí)施時(shí)進(jìn)行增減。
傳統(tǒng)的做法我們稱之為“重新開(kāi)發(fā)系統(tǒng)適應(yīng)新需求”方式。
隨著業(yè)務(wù)的迅速發(fā)展,采用傳統(tǒng)的方法代碼的改寫量越來(lái)越多,版本也越來(lái)越多,但一次改寫代碼都面臨危險(xiǎn),都要重新編譯,各省的業(yè)務(wù)要作不同處理,版本越來(lái)越多,系統(tǒng)變得越來(lái)越不穩(wěn)定,越來(lái)越難以維護(hù),人員的流動(dòng)使版本更是雪上加霜,迫切需要一種統(tǒng)一的、有柔韌性的、可擴(kuò)展解決方案,將變化和改動(dòng)集中于一點(diǎn),使設(shè)計(jì)更容易,維護(hù)人員更方便,而且這個(gè)方案要盡量減少代碼的修改量,最好是由配置解決,從而解決核心代碼的穩(wěn)定性, 如前所述,傳統(tǒng)的“重新開(kāi)發(fā)系統(tǒng)適用新需求”的解決方案,已經(jīng)產(chǎn)生系統(tǒng)難以適應(yīng)電信運(yùn)營(yíng)商業(yè)務(wù)發(fā)展,難以適應(yīng)運(yùn)營(yíng)商需求,系統(tǒng)也難以維護(hù)的情況。通過(guò)多年在電信領(lǐng)域的經(jīng)驗(yàn),并通過(guò)了解設(shè)計(jì)模式,我們了解到在諸多模式中有一種叫interpreter模式,該模式核心思想是讓程序在運(yùn)行期間可以解釋配置信息,生成機(jī)器代碼,從而達(dá)到不修改代碼,由配置來(lái)解決問(wèn)題的目的,由此決定基于解釋器模式,并結(jié)合其他設(shè)計(jì)模式,設(shè)計(jì)一種基于動(dòng)態(tài)編譯技術(shù)的解決方案,從而徹底解決上述問(wèn)題。這種技術(shù)就是“基于解析器的動(dòng)態(tài)編譯技術(shù)”。
發(fā)明內(nèi)容
本發(fā)明的目的是復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的實(shí)現(xiàn)采用構(gòu)件化設(shè)計(jì)思想進(jìn)行設(shè)計(jì)。該方法可以作為獨(dú)立的可配置的應(yīng)用模塊存在于應(yīng)用平臺(tái),采用compositor模式進(jìn)行設(shè)計(jì),使用二叉搜索樹(shù)放置變量列表,可以快速定位到變量。
本發(fā)明的技術(shù)解決方案是復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的實(shí)現(xiàn)方法,采用構(gòu)件化設(shè)計(jì),采用compositor(編譯)模式進(jìn)行設(shè)計(jì),使用二叉搜索樹(shù)放置變量列表,快速定位到變量,該方法同時(shí)包括編譯和解釋2個(gè)部分,對(duì)于一條業(yè)務(wù)規(guī)則只編譯一次,在編譯之后不再重新解釋,變成純粹的內(nèi)存操作,即變成對(duì)compositor節(jié)點(diǎn)樹(shù)的操作,從而以極快的速度完成業(yè)務(wù)解析。
本發(fā)明將各利配置方式,業(yè)務(wù)配置集中于一點(diǎn),在增加修改業(yè)務(wù),系統(tǒng)維護(hù)時(shí)只要找到專門的配置文件,修改特定的配置項(xiàng)或新增配置項(xiàng)即可解決業(yè)務(wù)修改和新增的業(yè)務(wù)等問(wèn)題。
本發(fā)明采用外部的字符串影射系統(tǒng)內(nèi)存中的變量,通過(guò)修改字符串值來(lái)修改內(nèi)部變量,通過(guò)預(yù)先定義的函數(shù)完成業(yè)務(wù)變換。
本發(fā)明適用于每一種支持標(biāo)準(zhǔn)c/c++的系統(tǒng)都可使用該方法。
本發(fā)明動(dòng)態(tài)編譯過(guò)程中按如下步驟編譯過(guò)程如下讀入規(guī)則\判斷操作符號(hào)\根據(jù)操作符號(hào)進(jìn)行\(zhòng)生成解釋器語(yǔ)法樹(shù)解釋過(guò)程如下調(diào)用動(dòng)態(tài)編譯內(nèi)存綁定接口綁定內(nèi)存變量,讀入動(dòng)態(tài)編譯規(guī)則。調(diào)用編譯過(guò)程生成內(nèi)存語(yǔ)法樹(shù);讀取話單,把話單變量綁定到動(dòng)態(tài)編譯變量?jī)?nèi)存,調(diào)用語(yǔ)法樹(shù)解析接口生成結(jié)果,解析接口調(diào)用解析樹(shù),反復(fù)遞歸得;系統(tǒng)根據(jù)語(yǔ)法樹(shù)接口的處理進(jìn)行相應(yīng)處理。
該發(fā)明同時(shí)包括編譯和解釋2個(gè)部分,對(duì)于一條業(yè)務(wù)規(guī)則編譯只需一次,在編譯之后不再重新解釋,變成純粹的內(nèi)存操作,即變成對(duì)compositor節(jié)點(diǎn)樹(shù)的操作,從而以極快的速度完成業(yè)務(wù)解析。采用解釋器方式的優(yōu)點(diǎn)在于 1、由配置解決問(wèn)題,可無(wú)限擴(kuò)展; 2、不需要修改核心代碼,核心代碼相對(duì)穩(wěn)定; 3、不需要重新編譯,便于移植; 4、可自由增減業(yè)務(wù)規(guī)則,容易維護(hù)。
本發(fā)明的特點(diǎn)是在電信計(jì)費(fèi)系統(tǒng)的實(shí)際使用表明,極大提高的編碼的工作量,在設(shè)計(jì)過(guò)程中,只對(duì)核心通用業(yè)務(wù)進(jìn)行處理,而把各省的特殊業(yè)務(wù)事先預(yù)留接口,由動(dòng)態(tài)解釋器完成。
在項(xiàng)目維護(hù)過(guò)程中,對(duì)各省系統(tǒng)得新增需求首先采用動(dòng)態(tài)編譯的思想,配置動(dòng)態(tài)編譯規(guī)則,不需修改任何代碼,完成用戶需求。
在電信綜合結(jié)算系統(tǒng)的模塊都可以見(jiàn)到動(dòng)態(tài)編譯的使用,從預(yù)處理,批價(jià),分揀,上傳下發(fā)都可以自由的調(diào)用動(dòng)態(tài)編譯接口,無(wú)需重編碼,重編譯,提升了系統(tǒng)的安全性。動(dòng)態(tài)編譯經(jīng)過(guò)改造,能以極快的速度運(yùn)行,做到對(duì)程序性能基本沒(méi)有影響。
圖1是本發(fā)明編譯過(guò)程示意圖 圖2是本發(fā)明解釋過(guò)程示意圖
具體實(shí)施例方式 具體實(shí)現(xiàn)方案參見(jiàn)附圖。動(dòng)態(tài)編譯采用構(gòu)件化設(shè)計(jì)思想進(jìn)行設(shè)計(jì)。該技術(shù)可以作為獨(dú)立的模塊可被各需要運(yùn)用動(dòng)態(tài)編譯功能的模塊調(diào)用,只要配置文件中配置動(dòng)態(tài)編譯規(guī)則,動(dòng)態(tài)編譯規(guī)則中的常量應(yīng)用程序中要有定義,規(guī)則中的函數(shù)模塊已實(shí)現(xiàn)即可。
動(dòng)態(tài)編譯的幾個(gè)關(guān)鍵對(duì)象類設(shè)計(jì)如下 ●VariantList類,該類定義變量列表,該類包含一個(gè)二叉搜索樹(shù),樹(shù)的節(jié)點(diǎn)由一個(gè)字符串為查找鍵和一個(gè)內(nèi)存地址組成,使用二叉搜索樹(shù)可以在對(duì)數(shù)時(shí)間搜索到變量,從而得到變量的值或進(jìn)行修改; ●Expression(解釋)功能類及子類,該類為compositor模式的實(shí)現(xiàn),Expression為純虛類,表達(dá)式類都繼承自Expression,包含不可遞歸節(jié)點(diǎn)類(也就是不含一個(gè)Expression的一個(gè)指針)的常量類和變量類,和其他可遞歸節(jié)點(diǎn)類(包含Expression的一個(gè)和多個(gè)指針),可遞歸節(jié)點(diǎn)完成與,或,非,和其他自定義函數(shù),最后一個(gè)Expression的實(shí)例成為語(yǔ)法樹(shù); ●Interpreter類,該類負(fù)責(zé)解釋動(dòng)態(tài)編譯規(guī)則字符串,生成語(yǔ)法樹(shù); ●Compile類,該類為包裝類,提供所有的調(diào)用接口 動(dòng)態(tài)編譯的業(yè)務(wù)規(guī)則的配置方式 輸入項(xiàng)輸入為一個(gè)字符串表達(dá)式,具體語(yǔ)法規(guī)則如下
變量名變量是以’$’符號(hào)開(kāi)始的,變量名可以為字母,也可以為變量名+字母。
表達(dá)式表達(dá)式可以是以操作值+操作符+操作值的形式,也可以是表達(dá)式+操作符+操作值的形式。
操作值可以是表達(dá)式,可以是以單引號(hào)”括起來(lái)的任意字符,可以是$變量名,可以是函數(shù)名(或者函數(shù)的參數(shù)),也可以是數(shù)字。
函數(shù)參數(shù)可以是任意表達(dá)式。
操作符邏輯與’and’符號(hào),或者邏輯或’or’符號(hào),運(yùn)算符號(hào)’+,’-,’*’,’/’。
輸出項(xiàng)表達(dá)式是否符合語(yǔ)法規(guī)則的標(biāo)識(shí)、表達(dá)式的運(yùn)算結(jié)果。
編譯類的結(jié)構(gòu)定義如下 public: Interpreter(){m_SyntaxTree.push_back(NULL);} ~Interpreter(); bool DcfineVariable(const char *VariableName,const char *VariableAddress); const char *Operation(char *Result,int Length,int *Error,const char *Context); void DumpVar(void){} //私有類 private: //解釋器各種表達(dá)式基類<!-- SIPO <DP n="3"> --><dp n="d3"/> class Expression public: Expression(){} virtual ~Expression(){} virtual const char *Execute()=0; virtual const char *SyntaxAnalyze(Interpreter *pInterpreter,const char*Context,int &ErrorNo)=0; virtual const char *ExpType(){return(const char *)"Expression";} friend class Expression; //終結(jié)符表達(dá)式,葉子節(jié)點(diǎn)不需要在進(jìn)行語(yǔ)法分析 //語(yǔ)法樹(shù)中的葉子結(jié)點(diǎn),一些常量字符串,如’11’,’12’,’011’等 class LiteralExp:public Expression { public: explicit LiteralExp(const char *Literal):m_Literal(Literal){} virtual ~LiteralExp(){} const char *Execute(){return m_Literal.c_str();} const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo){return NULL;} const char *ExpType(){return(const char *)"LiteralExp";} private: string m_Literal;}; friend class LiteralExp; //表達(dá)式中出現(xiàn)的變量,語(yǔ)法樹(shù)中的葉子結(jié)點(diǎn) class VariableExp:public Expression { public: explicit VariableExp(const char *pVarAddress):m_pVarAddress(pVarAddress){} ~VariableExp(){} const char *Execute(){return m_pVarAddress;} const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo){return NULL;} const char *ExpType(){return(const char *)"VariableExp";} private: const char *m_pVarAddress;}; friend class VariableExp; //函數(shù)表達(dá)式 //like(exp1,exp2) class LikeExp:public Expression { public: LikeExp():m_LeftExp(0),m_RightExp(0){} ~LikeExp(); const char *Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"LikeExp";} private:<!-- SIPO <DP n="4"> --><dp n="d4"/> bool Compare(const char *CompareString,const char *CompareMod); Expression *m_LeftExp; Expression *m_RightExp;}; friend class LikeExp; //not(exp) class NotExp:public Expression { public: NotExp():m_BoolExp(0){} ~NotExp(); const char *Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"NotExp";} private: Expression *m_BoolExp;}; friend class NotExp; //if(exp,true_return,false_return) class IfExp:public Expression { public: IfExp():m_BoolExp(0),m_True_RetExp(0),m_False_RetExp(0){} ~IfExp(); const char *Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"IfExp";} private: Expression *m_BoolExp; Expression *m_True_RetExp; Expression *m_False_RetExp;}; friend class IfExp; //case(conditionl,result1,condition2,result2,....,default_result) class CaseExp:public Expression { public: CaseExp(){} ~CaseExp(); const char * Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"CaseExp";} private: vector<Expression *>m_ExpArray;}; friend class CaseExp; //bool_expl and bool_exp2 class AndExp:public Expression { public:<!-- SIPO <DP n="5"> --><dp n="d5"/> AndExp():m_LeftCondition(0),m_RightCondition(0){}; ~AndExp() { delete m_LeftCondition; delete m_RightCondition;} const char * Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo){return NULL;} const char *ExpType(){return(const char *)"AndExp";} void AddLeftExp(Expression *LeftExp){m_LeftCondition=LeftExp;}void AddRightExp(Expression *RightExp){m_RightCondition=RightExp;} private: Expression *m_LeftCondition; Expression *m_RightCondition;}; friend class AndExp; //bool_exp1 or bool_exp2 class OrExp:public Expression { public: OrExp():m_LeftCondition(0),m_RightCondition(0){}; ~OrExp() { delete m_LeftCondition; delete m_RightCondition; } const char * Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo){return NULL;} const char *ExpType(){return(const char *)"OrExp";} void AddLeftExp(Expression *LeftExp){m_LeftCondition=LeftExp;} void AddRightExp(Expression *RightExp){m_RightCondition=RightExp;} private: Expression *m_LeftCondition; Expression *m_RightCondition;}; friend class OrExp; //in(value,test_value1,test_value2,....) class InExp:public Expression { public: InExp(){}; ~InExp(); const char * Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"InExp";} private: vector<Expression *>m_ExpArray;}; friend class InExp; //substring(string,{-}pos{,length})pos為正時(shí)從左到右從1開(kāi)始,pos為負(fù)時(shí)從右往左從-1開(kāi)始<!-- SIPO <DP n="6"> --><dp n="d6"/> //如果忽略length表示取到字符串末尾 class SubStringExp:public Expression { public: SubStringExp():m_StringExp(0),m_PosExp(0),m_LenExp(0){} ~SubStringExp(); const char * Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"SubStringExp";} private: Expression *m_StringExp; Expression *m_PosExp; Expression *m_LenExp; //存放結(jié)果 char m_Buffer[255];}; friend class SubStringExp; //connect(string1,string2) class ConnectExp:public Expression { public: ConnectExp():m_FirstStrExp(0),m_SecondStrExp(0){} ~ConnectExp(); const char * Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"ConnectExp";} private: Expression *m_FirstStrExp; Expression *m_SecondStrExp; //存放結(jié)果 char m_Buffer[255];}; friend class ConnectExp; //set($VarExp,string) class SetExp:public Expression { public: SetExp():m_VariableExp(0),m_StringExp(0){} ~SetExp(); const char * Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"SetExp";} private: Expression *m_VariableExp; Expression *m_StringExp;}; friend class SetExp; //strabove(string1,string2)|strbelow(string1,string2)<!-- SIPO <DP n="7"> --><dp n="d7"/> class StrCmpExp:public Expression { public: explicitStrCmpExp(boolblsStrAbove):m_StringExp1(0),m_StringExp2(0),m_blsStrAboye(blsStrAbove){} ~StrCmpExp(); const char * Execute(); const char *SyntaxAnalyze(Interpreter *plnterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return m_blsStrAbove (const char*)"StrAbove":(const char *)"StrBelow";} private: Expression *m_StringExp1; Expression *m_StringExp2; bool m_blsStrAbove;}; friend class StrCmpExp; //numabove(numstring1,numstring2)|numbelow(numstring1,numstring2) class NumCmpExp:public Expression { public: explicitNumCmpExp(boolbNumStrAbove):m_NumStringExp1(0),m_NumStringExp2(0),m_bIsNumAbove(bNumStrAbove){} ~NumCmpExp(); const char*Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return m_bIsNumAbove (const char*)"NumAbove":(const char *)"NumBelow";} private: Expression *m_NumStringExp1; Expression *m_NumStringExp2; bool m_bIsNumAbove;}; friend class NumCmpExp; //isdatetime(string) class IsDateTimeExp:public Expression { public: explicit IsDateTimeExp():m_StringExp(0){} ~IsDateTimeExp(); const char * Execute(); const char *SyntaxAnaIyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"IsDateTimeExp";} private: Expression *m_StringExp; }; friend class IsDateTimeExp; //add by liusk 2003/10/23 //計(jì)算字符串長(zhǎng)度<!-- SIPO <DP n="8"> --><dp n="d8"/> //length(string) class LengthExp:public Expression { public: explicit LengthExp():m_StringExp(0){} ~LengthExp(); const char *Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"LengthExp";} private: char m_Length[30]; Expression *m_StringExp;}; friend class LengthExp; //add by liusk 2003/10/23 //如果value和搜索(serarch_n)列表中的任何一個(gè)相等則返回相應(yīng)的result,否則返回默認(rèn)值default_result //與case函數(shù)的不同為,case為條件測(cè)試滿足則返回,decode為比較測(cè)試與一系列的值比較如果滿足則返回對(duì)應(yīng)的結(jié)果 //decode(value_exp,search1,resultl,search2,result2,..,default_result) class DecodeExp:public Expression { public: explicit DecodeExp(){} ~DecodeExp(); const char *Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"DecodeExp";} private: vector<Expression *>m_ExpArray;}; friend class DecodeExp; //add by liusk 2003/11/8 //comma(exp1,exp2,exp3,....,expn) //逗號(hào)表達(dá)式,執(zhí)行所有的表達(dá)式語(yǔ)句,但返回最后一個(gè)表達(dá)式的值 //可做一些表達(dá)式的容器 class CommaExp:public Expression { public: expliciy CommaExp(){} ~CommaExp(); const char * Execute(); const char *SyntaxAnalyze(Interpreter *pInterpreter,const char *Context,int &ErrorNo); const char *ExpType(){return(const char *)"CommaExp";} private: vector<Expression *>m_ExpArray;}; friend class CommaExp;<!-- SIPO <DP n="9"> --><dp n="d9"/> private: //變量列表 map<string,const char *>m_VaribleList; //索引0未使用 veetor<Expression *>m_SyntaxTree; //語(yǔ)法分析過(guò)程const char *CompileExp(const char *Context,Expression **SyntaxTree,int &ErrorNo); const char *ValueExp(const char *Context,Expression **SyntaxTree,int &ErrorNo);} 該類中主要方法Operation()的實(shí)現(xiàn)方法如下 //第一次編譯表達(dá)式時(shí)會(huì)強(qiáng)制修改表達(dá)式的前2個(gè)字節(jié) //第1個(gè)字節(jié)是已編譯標(biāo)志OxEE,第2個(gè)字節(jié)是索引號(hào) //建議在配規(guī)則時(shí)每條規(guī)則前面預(yù)留2個(gè)tab字符 //主要是為了能迅速定位一個(gè)表達(dá)式的語(yǔ)法樹(shù) const char *Interpreter::Operation(char *Result,int Length,int*ErrorNo,const char *Context) { *ErrorNo=COMPILE_NOERROR; if(*(unsigned char *)Context==OxEE) { //try{運(yùn)行時(shí)錯(cuò)誤編號(hào)COMPILE_RUNTIME_ //需由Expression對(duì)象拋出異常try //取表達(dá)式的索引編號(hào) return strncpy(Result,m_SyntaxTree[(unsigned int)*(Context+1)]->Execute(),Length);} catch(...){ *ErrorNo=COMPILE_RUNTIME_ERROR_UNKNOWN; return Result;} } else{ //表達(dá)式超過(guò)最大限制 //(索引編號(hào)使用一個(gè)字節(jié)存儲(chǔ)1~255,由于0是字符串結(jié)束標(biāo)志未使用0) if(m_SyntaxTree.size()>=256) { *ErrorNo=COMPILE_RUNTIME_ERROR_EXPOVERLIMIT; return Context;} Expression *pTempExp=NULL; const char *pPosition=NULL; pPosition=CompileExp(Context,&pTempExp,*ErrorNo); if(*ErrorNo !=COMPILE_NOERROR) { return pPosition; } //如還有剩余的字符串則說(shuō)明表達(dá)式不符文法規(guī)則 else if(*pPosition !=0) { *ErrorNo=COMPILE_ERROR_INVALID_EXP;<!-- SIPO <DP n="10"> --><dp n="d10"/> delete pTempExp; return pPosition;} //對(duì)表達(dá)式加索引,格式為OxEE索引編號(hào),從1~255 //注修改Context的第1個(gè)字節(jié)為OxEE(標(biāo)志),第2個(gè)字節(jié)為索引號(hào) *(unsigned char *)Context=OxEE; *(unsigned char *)(Context+1)=m_SyntaxTree.size(); m_SyntaxTree.push_back(pTempExp); return Operation(Result,Length,ErrorNo,Context);} 該方法將統(tǒng)一以前紛繁的配置方式,業(yè)務(wù)配置集中于一點(diǎn),在增加修改業(yè)務(wù),系統(tǒng)維護(hù)時(shí)只要找到專門的配置文件,修改特定的配置項(xiàng)或新增配置項(xiàng)即可解決業(yè)務(wù)修改和新增的業(yè)務(wù)等問(wèn)題。
以下是配置部分的代碼,“#”開(kāi)頭部分是注釋部分,業(yè)務(wù)規(guī)則中不作處理。“\”是表示下行繼續(xù)。
#業(yè)務(wù)通道標(biāo)志,網(wǎng)關(guān)局 [PP003] #無(wú)效話單規(guī)則,false為不做丟棄不作分揀,TRUE為做分揀 InvalidRule=’false’ #分揀規(guī)則數(shù) DispartRuleNum=2 #入網(wǎng)網(wǎng)間結(jié)算 DispartRule1=decode($InTrunkTsp,\ $LocalTsp,decode($OutTrunkTsp,’-2’,’12’,’false’),\ ’-2’,if(in($OutTrunkTsp,$LocalTsp,’-2’),’11’,’false’),\’11’) #出網(wǎng)網(wǎng)間結(jié)算 DispartRule2=if(in($OutTrunkTsp,$LocalTsp,’-2’),’false’,’12’) #分揀路徑規(guī)則 DispartPathRule=case(like($BusinessType,’1[12]’),’003’,’003’) 該技術(shù)采用外部的字符串影射系統(tǒng)內(nèi)存中的變量,通過(guò)修改字符串值來(lái)修改內(nèi)部變量,通過(guò)預(yù)先定義的函數(shù)完成業(yè)務(wù)變換,提高系統(tǒng)得靈活性,可維護(hù)性。
當(dāng)業(yè)務(wù)規(guī)則變化、新增新業(yè)務(wù)時(shí),只要修改該配置文件,不用修改代碼,即可實(shí)現(xiàn)對(duì)業(yè)務(wù)的更新處理。
該方法由電信業(yè)務(wù)產(chǎn)生,但不針對(duì)特定的模塊,每個(gè)系統(tǒng)模塊都可通過(guò)接口使用該技術(shù),該技術(shù)也不特定針對(duì)電信系統(tǒng),事實(shí)上每一種業(yè)務(wù)系統(tǒng)都可使用動(dòng)態(tài)編譯技術(shù)。
該發(fā)明有很好的移植性,動(dòng)態(tài)編譯技術(shù)的實(shí)現(xiàn)不針對(duì)特定的主機(jī),特定操作系統(tǒng),每一種支持標(biāo)準(zhǔn)c/c++的系統(tǒng)都可使用該技術(shù)。
以下是動(dòng)態(tài)編譯預(yù)處理和無(wú)動(dòng)態(tài)編譯預(yù)處理效率(if…else..方式)的測(cè)試情況 測(cè)試環(huán)境1)應(yīng)用服務(wù)器IBM P650 8CPU 8G MEM /CPU TYPEPowerPC_POWER4 測(cè)試對(duì)象預(yù)處理文件數(shù)為20;每個(gè)文件50000條記錄。
測(cè)試方法將文件放置于預(yù)處理輸入目錄,啟動(dòng)1個(gè)預(yù)處理進(jìn)程。
監(jiān)控輸入目錄的文件個(gè)數(shù)直至為零,同時(shí)監(jiān)控清單表數(shù)據(jù)記錄數(shù)。配置4條動(dòng)態(tài)編譯規(guī)則,每條規(guī)則大概包含15個(gè)條件判斷。
A、基于動(dòng)態(tài)編譯預(yù)處理測(cè)試 系統(tǒng)耗時(shí)205秒 處理速度1000000÷205約=4878條/秒 B、重新開(kāi)發(fā)系統(tǒng)適應(yīng)新需求方式的預(yù)處理測(cè)試 系統(tǒng)耗時(shí)198秒 處理速度1000000÷43.5約=5050條/秒 測(cè)試結(jié)論速度基本相當(dāng)。
使用案例業(yè)務(wù)需求A省的電信綜合結(jié)算系統(tǒng)要求將西門子交換機(jī)(編號(hào)102)只輸出cf(35),transit(31)二種話單,而B(niǎo)省電信綜合結(jié)算系統(tǒng)要求將西門子交換機(jī)(編號(hào)102)輸出cf(35),moc(32),mtc(33)三種話單 傳統(tǒng)的解決辦法對(duì)A省和而B(niǎo)省各做一個(gè)版本,分別用if語(yǔ)句來(lái)控制實(shí)現(xiàn)。
只為A省和而B(niǎo)省在動(dòng)態(tài)編譯的配置文件中各配置一條不同的動(dòng)態(tài)編譯規(guī)則,即可解決。
A省Case(case($sourceid,”102”)and(case($recordtype,”31”)or case($recordtype,”35”)),”true”) B省 Case(case($sourceid,”102”)and(case($recordtype,”32”) or case($recordtype,”33”) orcase($recordtype,”35”)),”true”) 從以上可以看出,基于動(dòng)態(tài)編譯的解決方案做到了版本獨(dú)立,不同業(yè)務(wù)由配置解決。
權(quán)利要求
1、復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的實(shí)現(xiàn)方法,采用構(gòu)件化設(shè)計(jì),其特征是采用編譯模式進(jìn)行設(shè)計(jì),使用二叉搜索樹(shù)放置變量列表,快速定位到變量,該方法同時(shí)包括編譯和解釋2個(gè)部分,對(duì)于一條業(yè)務(wù)規(guī)則只編譯一次,在編譯之后不再重新解釋,變成純粹的內(nèi)存操作,即變成對(duì)編譯節(jié)點(diǎn)樹(shù)的操作,從而以極快的速度完成業(yè)務(wù)解析。
2、由權(quán)利要求1所述的復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的實(shí)現(xiàn)方法,其特征是將各種配置方式,業(yè)務(wù)配置集中于一點(diǎn),在增加修改業(yè)務(wù),系統(tǒng)維護(hù)時(shí)只要找到專門的配置文件,修改特定的配置項(xiàng)或新增配置項(xiàng)即可解決業(yè)務(wù)修改和新增的業(yè)務(wù)等問(wèn)題。
3、由權(quán)利要求1所述的復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的實(shí)現(xiàn)方法,其特征是采用外部的字符串影射系統(tǒng)內(nèi)存中的變量,通過(guò)修改字符串值來(lái)修改內(nèi)部變量,通過(guò)預(yù)先定義的函數(shù)完成業(yè)務(wù)變換。
4、由權(quán)利要求1所述的復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的實(shí)現(xiàn)方法,其特征是適用于每一種支持標(biāo)準(zhǔn)c/c++的系統(tǒng)都可使用該方法。
5、由權(quán)利要求1所述的復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的實(shí)現(xiàn)方法,其特征是動(dòng)態(tài)編譯過(guò)程中按如下步驟編譯過(guò)程如下讀入規(guī)則\判斷操作符號(hào)\根據(jù)操作符號(hào)進(jìn)行\(zhòng)生成解釋器語(yǔ)法樹(shù)解釋過(guò)程如下調(diào)用動(dòng)態(tài)編譯內(nèi)存綁定接口綁定內(nèi)存變量,讀入動(dòng)態(tài)編譯規(guī)則。調(diào)用編譯過(guò)程生成內(nèi)存語(yǔ)法樹(shù);讀取話單,把話單變量綁定到動(dòng)態(tài)編譯變量?jī)?nèi)存,調(diào)用語(yǔ)法樹(shù)解析接口生成結(jié)果,解析接口調(diào)用解析樹(shù),反復(fù)遞歸得;系統(tǒng)根據(jù)語(yǔ)法樹(shù)接口的處理進(jìn)行相應(yīng)處理。
6、由權(quán)利要求1所述的復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的實(shí)現(xiàn)方法,其特征是動(dòng)態(tài)編譯的關(guān)鍵對(duì)象類的設(shè)計(jì)是,VariantList類,該類定義變量列表,該類包含一個(gè)二叉搜索樹(shù),樹(shù)的節(jié)點(diǎn)由一個(gè)字符串為查找鍵和一個(gè)內(nèi)存地址組成,使用二叉搜索樹(shù)可以在對(duì)數(shù)時(shí)間搜索到變量,從而得到變量的值或進(jìn)行修改;
●Expression功能類及子類,該類為compositor模式的實(shí)現(xiàn),Expression為純虛類,表達(dá)式類都繼承自Expression,包含不可遞歸節(jié)點(diǎn)類(也就是不含一個(gè)Expression的一個(gè)指針)的常量類和變量類,和其他可遞歸節(jié)點(diǎn)類(包含Expression的一個(gè)和多個(gè)指針),可遞歸節(jié)點(diǎn)完成與,或,非,和其他自定義函數(shù),最后一個(gè)Expression的實(shí)例成為語(yǔ)法樹(shù);
●Interpreter類,該類負(fù)責(zé)解釋動(dòng)態(tài)編譯規(guī)則字符串,生成語(yǔ)法樹(shù);
●Compile類,該類為包裝類,提供所有的調(diào)用接口,
動(dòng)態(tài)編譯的業(yè)務(wù)規(guī)則的配置方式,
輸入項(xiàng)輸入為一個(gè)字符串表達(dá)式,
輸出項(xiàng)表達(dá)式是否符合語(yǔ)法規(guī)則的標(biāo)識(shí)、表達(dá)式的運(yùn)算結(jié)果。
全文摘要
復(fù)雜多業(yè)務(wù)的動(dòng)態(tài)編譯器的實(shí)現(xiàn)方法,采用構(gòu)件化設(shè)計(jì),采用compositor模式進(jìn)行設(shè)計(jì),使用二叉搜索樹(shù)放置變量列表,快速定位到變量,該方法同時(shí)包括編譯和解釋2個(gè)部分,對(duì)于一條業(yè)務(wù)規(guī)則只編譯一次,在編譯之后不再重新解釋,變成純粹的內(nèi)存操作,即變成對(duì)compositor節(jié)點(diǎn)樹(shù)的操作,從而以極快的速度完成業(yè)務(wù)解析。本發(fā)明的特點(diǎn)是在電信計(jì)費(fèi)系統(tǒng)的實(shí)際使用表明,極大提高的編碼的工作量,在設(shè)計(jì)過(guò)程中,只對(duì)核心通用業(yè)務(wù)進(jìn)行處理,而把各省的特殊業(yè)務(wù)事先預(yù)留接口,由動(dòng)態(tài)解釋器完成。
文檔編號(hào)H04M15/00GK1896954SQ200610106550
公開(kāi)日2007年1月17日 申請(qǐng)日期2006年7月12日 優(yōu)先權(quán)日2006年4月27日
發(fā)明者邵九松, 黃誠(chéng), 王濤, 俞東, 紀(jì)振華, 柏松, 施大偉, 周仲華, 歐小祥, 周連華 申請(qǐng)人:南京聯(lián)創(chuàng)科技股份有限公司