專利名稱::一種高效易維護(hù)有限狀態(tài)機(jī)的實(shí)現(xiàn)方法
技術(shù)領(lǐng)域:
:本發(fā)明涉及一種實(shí)現(xiàn)有限狀態(tài)機(jī)的方法,尤其涉及一種實(shí)現(xiàn)具有高效率,且便于維護(hù)的有限狀態(tài)機(jī)的方法,屬于計(jì)算機(jī)編譯
技術(shù)領(lǐng)域:
。
背景技術(shù):
:有限自動(dòng)機(jī)(FiniteAutomataMachine)是計(jì)算機(jī)科學(xué)的重要基石,它在軟件開發(fā)領(lǐng)域內(nèi)通常被稱作有限狀態(tài)機(jī)(FiniteStateMachine),是一種應(yīng)用非常廣泛的軟件設(shè)計(jì)模式(DesignPattern)。有限狀態(tài)機(jī)是一種用來進(jìn)行對(duì)象行為建模的工具,其作用主要是描述對(duì)象在它的生命周期內(nèi)所經(jīng)歷的狀態(tài)序列,以及如何響應(yīng)來自外界的各種事件。與其他常用的設(shè)計(jì)模式有所不同,程序員要想在自己的軟件中加入有限狀態(tài)機(jī)時(shí),必須再額外編寫一部分用于邏輯控制的代碼,如果系統(tǒng)足夠復(fù)雜的話,這部分代碼的實(shí)現(xiàn)和維護(hù)相當(dāng)困難。目前在實(shí)現(xiàn)有限狀態(tài)機(jī)時(shí),常見的方法有以下兩種方法一使用switch-case語句。這是最簡(jiǎn)單也是最直接的一種方式,其基本思路是為狀態(tài)機(jī)中的每一種狀態(tài)都設(shè)置一個(gè)case分支,專門用于對(duì)該狀態(tài)進(jìn)行控制。使用switch-case語句實(shí)現(xiàn)的有限狀態(tài)機(jī)能夠很好地工作,但代碼的可讀性并不十分理想,主要原因是在實(shí)現(xiàn)狀態(tài)之間的轉(zhuǎn)換時(shí),檢查轉(zhuǎn)換條件和進(jìn)行狀態(tài)轉(zhuǎn)換都是混雜在當(dāng)前狀態(tài)中完成的。顯然,如果在每種狀態(tài)下都需要分別檢查多個(gè)不同的轉(zhuǎn)換條件,并且需要根據(jù)檢查結(jié)果讓狀態(tài)機(jī)切換到不同的狀態(tài),那么這樣的代碼將是枯燥而難懂的。在很長(zhǎng)一段時(shí)期內(nèi),使用switch-case語句一直是實(shí)現(xiàn)有限狀態(tài)機(jī)的唯一方法,甚至像編譯器這樣復(fù)雜的軟件系統(tǒng),大部分也都直接采用這種實(shí)現(xiàn)方式。但隨著狀態(tài)機(jī)應(yīng)用的逐漸深入,構(gòu)造出來的狀態(tài)機(jī)越來越復(fù)雜,這種方法也開始面臨各種嚴(yán)峻的考驗(yàn),其中最令人頭痛的是,如果狀態(tài)機(jī)中的狀態(tài)非常多,或者狀態(tài)之間的轉(zhuǎn)換關(guān)系異常復(fù)雜,那么簡(jiǎn)單地使用switch-case語句構(gòu)造出來的狀態(tài)機(jī)將是不可維護(hù)的。方法二使用函數(shù)指針數(shù)組。因?yàn)橛邢逘顟B(tài)機(jī)本質(zhì)上就是一個(gè)“狀態(tài)-事件”二維矩陣問題,因此在實(shí)現(xiàn)上可以采用二維函數(shù)指針數(shù)組的方法,形如(*processs)()process_function[state][event]的形式。這種方法的缺陷是event(事件)的編號(hào)必須從0開始連續(xù)編號(hào),如果某個(gè)狀態(tài)下增加一個(gè)事件,其它狀態(tài)即使不需要考慮這個(gè)事件,也需要增加相應(yīng)的處理,以保證矩陣的完整性。當(dāng)系統(tǒng)復(fù)雜到一定程度時(shí)維護(hù)性就很差,甚至不可維護(hù)。
發(fā)明內(nèi)容本發(fā)明的目的在于提供一種新的實(shí)現(xiàn)有限狀態(tài)機(jī)的方法。該方法實(shí)現(xiàn)的有限狀態(tài)機(jī)既能保證高效,又簡(jiǎn)單易維護(hù),并且可適用于任何系統(tǒng)。為實(shí)現(xiàn)上述的發(fā)明目的,本發(fā)明采用下述的技術(shù)方案一種高效易維護(hù)有限狀態(tài)機(jī)的實(shí)現(xiàn)方法,其特征在于將有限狀態(tài)機(jī)中狀態(tài)與事件之間的關(guān)系分為兩層,第一層為狀態(tài)值的索引,第二層為每一狀態(tài)下需要處理的事件和該事件相應(yīng)的處理函數(shù);通過所述第一層的狀態(tài)值索引,搜索是否有需要處理的事件,若有,則進(jìn)入第二層,獲得與所述需要處理的事件相應(yīng)的處理函數(shù);若沒有,則執(zhí)行返回語句或輸出提示信息。所述第一層中,以當(dāng)前狀態(tài)值為索引建立一級(jí)表“狀態(tài)—事件跳轉(zhuǎn)表”。所述“狀態(tài)—事件跳轉(zhuǎn)表”中,數(shù)組下標(biāo)為狀態(tài)編號(hào),編號(hào)從0開始。所述第二層中,為每一個(gè)狀態(tài)分別建立二級(jí)表“狀態(tài)—事件處理表”。所述“狀態(tài)—事件處理表”中,對(duì)不同的事件和相應(yīng)的處理函數(shù)加以編號(hào),所述編號(hào)為任意編號(hào)。各所述“狀態(tài)—事件處理表”之間互不影響。所述“狀態(tài)—事件處理表”中,以0xFFFF作為結(jié)束標(biāo)志。本發(fā)明采用二級(jí)表結(jié)構(gòu)實(shí)現(xiàn)高效易維護(hù)的有限狀態(tài)機(jī),一級(jí)表是“狀態(tài)—事件跳轉(zhuǎn)表”,二級(jí)表是“狀態(tài)—事件處理表”。采用查表方式,實(shí)現(xiàn)“狀態(tài)—事件”處理。這樣實(shí)現(xiàn)的有限狀態(tài)機(jī)結(jié)構(gòu)清晰,既高效又簡(jiǎn)單易維護(hù)。下面結(jié)合附圖和具體實(shí)施方式對(duì)本發(fā)明作進(jìn)一步的說明。圖1為本發(fā)明所述方法的實(shí)施示意圖。具體實(shí)施例方式作為計(jì)算機(jī)編譯領(lǐng)域的公知常識(shí),有限狀態(tài)機(jī)分為兩種基本形態(tài),分別是不確定性有限狀態(tài)機(jī)(NFA)和確定性有限狀態(tài)機(jī)(DFA)。不確定性有限狀態(tài)機(jī)NFAM是一個(gè)五元式M=(Q,Vt∪{ε},δ,q0,F(xiàn)),其中Q有窮狀態(tài)集合;Vt∪{ε}輸入事件表與空串所組成的集合之和。即狀態(tài)機(jī)狀態(tài)轉(zhuǎn)換函數(shù)中的變量可以是輸入事件表中的事件,也可以是空串ε;δ狀態(tài)轉(zhuǎn)換函數(shù),為Q×Vt∪{ε}->2Q,其中2Q為Q的冪集;q0開始狀態(tài)F終止?fàn)顟B(tài)集,F(xiàn)Q確定性有限狀態(tài)機(jī)M’是一個(gè)五元式M’={Q,Vt,δ,q0,F(xiàn)},其中Q有窮狀態(tài)集合;Vt輸入事件表;δ狀態(tài)轉(zhuǎn)換函數(shù),為Q×Vt->Q的映射;q0開始狀態(tài),q0∈Q;F終止?fàn)顟B(tài)集,F(xiàn)Q.函數(shù)δ定義狀態(tài)轉(zhuǎn)換,用δ(q,a)=p表示,其中,q、p∈Q,a∈Vt。δ指示當(dāng)狀態(tài)機(jī)處于狀態(tài)q,且a是下一個(gè)輸入字符時(shí),狀態(tài)機(jī)狀態(tài)將由q變成p。所謂確定有限狀態(tài)機(jī)是指該狀態(tài)機(jī)只有一個(gè)開始狀態(tài)q0,且δ是單值函數(shù)。不確定性有限狀態(tài)機(jī)(NFA)和確定性有限狀態(tài)機(jī)(DFA)的主要區(qū)別在于狀態(tài)轉(zhuǎn)移函數(shù)不一樣。NFA對(duì)同一個(gè)字符串輸入完全有可能有多種理解方式,而DFA則只有唯一的一種理解方式。作為形式語言的基本常識(shí),不確定性有限狀態(tài)機(jī)和確定性有限狀態(tài)機(jī)在數(shù)學(xué)上是等價(jià)的,可以相互轉(zhuǎn)換。轉(zhuǎn)換的方法可以采用現(xiàn)在廣泛采用的子集化算法。本發(fā)明所述的實(shí)現(xiàn)高效、易維護(hù)有限狀態(tài)機(jī)的方法的核心思想在于將原有單層邏輯結(jié)構(gòu)的有限狀態(tài)機(jī)加以分解,使原有單層次的“狀態(tài)”—“事件”關(guān)系分為兩層,即用二級(jí)表結(jié)構(gòu)來實(shí)現(xiàn)有限狀態(tài)機(jī)。其中,以有窮狀態(tài)集合Q中的當(dāng)前狀態(tài)值為索引建立一級(jí)表—“狀態(tài)—事件跳轉(zhuǎn)表”;以每個(gè)狀態(tài)的事件號(hào)和相關(guān)的處理函數(shù)為基礎(chǔ)構(gòu)建二級(jí)表—“狀態(tài)—事件處理表”。參照?qǐng)D1所示,在有限狀態(tài)機(jī)中,采用查表方式實(shí)現(xiàn)“狀態(tài)—事件”處理。若表中有需要處理的事件,則跳轉(zhuǎn)到相應(yīng)的處理函數(shù);若沒有,則跳轉(zhuǎn)到默認(rèn)處理函數(shù)。該默認(rèn)處理函數(shù)執(zhí)行返回語句或輸出適當(dāng)?shù)奶崾拘畔ⅰ榇?,作為本方法的第一步是定義有限狀態(tài)機(jī)的結(jié)構(gòu)。其具體的內(nèi)容主要包括事件編號(hào)和相應(yīng)的處理函數(shù)。實(shí)現(xiàn)這一步的偽代碼如下所示//狀態(tài)機(jī)定義typedefstruct{unsignedintevent;//事件編號(hào)void(*process_func)();//處理函數(shù)}STATE_MC;作為下一步,需要進(jìn)一步定義每個(gè)狀態(tài)的“狀態(tài)—事件處理表”。“狀態(tài)—事件處理表”具體包括該狀態(tài)下需要處理的事件和該事件相應(yīng)的處理函數(shù)。在“狀態(tài)—事件處理表”中,事件號(hào)可以隨意編號(hào),表項(xiàng)可以任意增刪,不同表之間互不影響。作為一個(gè)實(shí)施例,處理表以0xFFFF作為結(jié)束標(biāo)志,對(duì)應(yīng)著默認(rèn)處理函數(shù)。該結(jié)束標(biāo)志也可以采用其它的字符來表示。實(shí)現(xiàn)本步驟的偽代碼如下所示//各個(gè)狀態(tài)的狀態(tài)-事件處理表//state0STATE_MCstate_0[]={{event_1,st0_event_1_process},//狀態(tài)0下對(duì)事件1的處理,處理函數(shù)st0_event1_process{event_2,st0_event2_process},//狀態(tài)0下對(duì)事件2的處理,處理函數(shù)st0_event2_process……{0xFFFF,st0_default_process}//默認(rèn)處理};//state1STATE_MCstate_1[]={{event_1,st1_event1_process},//狀態(tài)1下對(duì)事件1的處理,處理函數(shù)st1_event1_process{event_2,st1_event2_process},//狀態(tài)1下對(duì)事件2的處理,處理函數(shù)st1_event2_process……{0xFFFF,st1_default_process}//默認(rèn)處理};……//statenSTATE_MCstate_n[]={{event_1,stn_event1_process},//狀態(tài)n下對(duì)事件1的處理,處理函數(shù)stn_event1_process{event_2,stn_event2_process},//狀態(tài)n下對(duì)事件2的處理,處理函數(shù)stn_event2_process……{0xFFFF,stn_default_process}//默認(rèn)處理};第三步是定義“狀態(tài)—事件跳轉(zhuǎn)表”。該表的數(shù)組下標(biāo)為狀態(tài)編號(hào),編號(hào)從0開始。其成員為每個(gè)狀態(tài)的“狀態(tài)—事件處理表”地址。實(shí)現(xiàn)這一步的偽代碼如下所示//狀態(tài)-事件跳轉(zhuǎn)表//state-eventjumptableSTATE_MC*jump[MAX_STATE]={state_0,state_1,……,state_n};第四步是定義有限狀態(tài)機(jī)入口函數(shù)。這個(gè)入口函數(shù)實(shí)際上就是一個(gè)查表函數(shù),首先以當(dāng)前狀態(tài)值為索引得到“狀態(tài)—事件處理表”入口,搜索表中是否有需要處理的事件,若有,則跳轉(zhuǎn)到相應(yīng)的處理函數(shù);若沒有,則跳轉(zhuǎn)到默認(rèn)處理函數(shù)。這一步驟的偽碼如下所示//有限狀態(tài)機(jī)入口函數(shù)voidevent_process(unsignedintCurState,unsignedintEventNo){STATE_M*base;//查表,跳轉(zhuǎn)到相應(yīng)的服務(wù)函數(shù)base=j(luò)ump[CurState];while((base->event?。紼ventNo)&&(base->event!=0xFFFF))base++;base->processfunc();return;}至此,完整地實(shí)現(xiàn)了一種新的實(shí)現(xiàn)有限狀態(tài)機(jī)的方法。用這種方法實(shí)現(xiàn)的有限狀態(tài)機(jī),維護(hù)工作變得非常簡(jiǎn)單。該維護(hù)工作主要是根據(jù)實(shí)際需要,維護(hù)一張“狀態(tài)—事件處理表”,查表程序做好之后可以一勞永逸?!盃顟B(tài)—事件處理表”的大小由實(shí)際應(yīng)用決定,某狀態(tài)下如果需要處理某事件,則增加一項(xiàng);如果不需要處理,則不用考慮?!盃顟B(tài)—事件處理表”中,事件號(hào)可以隨意編號(hào),表項(xiàng)可以任意增刪,不同表之間互不影響。以上對(duì)本發(fā)明進(jìn)行了詳細(xì)的說明,但顯然本發(fā)明的具體實(shí)現(xiàn)形式并不局限于此。對(duì)于本
技術(shù)領(lǐng)域:
的一般技術(shù)人員來說,在不背離本發(fā)明所述方法的精神和權(quán)利要求范圍的情況下對(duì)它進(jìn)行的各種顯而易見的改變都在本發(fā)明的保護(hù)范圍之內(nèi)。權(quán)利要求1.一種高效易維護(hù)有限狀態(tài)機(jī)的實(shí)現(xiàn)方法,其特征在于將有限狀態(tài)機(jī)中狀態(tài)與事件之間的關(guān)系分為兩層,第一層為狀態(tài)值的索引,第二層為每一狀態(tài)下需要處理的事件和該事件相應(yīng)的處理函數(shù);通過所述第一層的狀態(tài)值索引,搜索是否有需要處理的事件,若有,則進(jìn)入第二層,獲得與所述需要處理的事件相應(yīng)的處理函數(shù);若沒有,則執(zhí)行返回語句或輸出提示信息。2.如權(quán)利要求1所述的高效易維護(hù)有限狀態(tài)機(jī)的實(shí)現(xiàn)方法,其特征在于所述第一層中,以當(dāng)前狀態(tài)值為索引建立一級(jí)表“狀態(tài)-事件跳轉(zhuǎn)表”。3.如權(quán)利要求2所述的高效易維護(hù)有限狀態(tài)機(jī)的實(shí)現(xiàn)方法,其特征在于所述“狀態(tài)-事件跳轉(zhuǎn)表”中,數(shù)組下標(biāo)為狀態(tài)編號(hào),編號(hào)從0開始。4.如權(quán)利要求1所述的高效易維護(hù)有限狀態(tài)機(jī)的實(shí)現(xiàn)方法,其特征在于所述第二層中,為每一個(gè)狀態(tài)分別建立二級(jí)表“狀態(tài)-事件處理表”。5.如權(quán)利要求4所述的高效易維護(hù)有限狀態(tài)機(jī)的實(shí)現(xiàn)方法,其特征在于所述“狀態(tài)-事件處理表”中,對(duì)不同的事件和相應(yīng)的處理函數(shù)加以編號(hào),所述編號(hào)為任意編號(hào)。6.如權(quán)利要求4所述的高效易維護(hù)有限狀態(tài)機(jī)的實(shí)現(xiàn)方法,其特征在于各所述“狀態(tài)-事件處理表”之間互不影響。7.如權(quán)利要求4所述的高效易維護(hù)有限狀態(tài)機(jī)的實(shí)現(xiàn)方法,其特征在于所述“狀態(tài)-事件處理表”中,以0xFFFF作為結(jié)束標(biāo)志。全文摘要本發(fā)明涉及一種高效、易維護(hù)有限狀態(tài)機(jī)的實(shí)現(xiàn)方法。該方法采用二級(jí)表結(jié)構(gòu),一級(jí)表是“狀態(tài)-事件跳轉(zhuǎn)表”,二級(jí)表是“狀態(tài)-事件處理表”。采用查表方式,實(shí)現(xiàn)“狀態(tài)-事件”處理。若表中有需要處理的事件,則跳轉(zhuǎn)到相應(yīng)的處理函數(shù);若沒有,則跳轉(zhuǎn)到默認(rèn)的處理函數(shù)?!盃顟B(tài)-事件處理表”中,事件號(hào)可以隨意編號(hào),表項(xiàng)可以任意增刪,不同表之間互不影響。文檔編號(hào)G06F9/45GK1815448SQ20051004887公開日2006年8月9日申請(qǐng)日期2005年12月31日優(yōu)先權(quán)日2005年12月31日發(fā)明者于連慶申請(qǐng)人:北京佳訊飛鴻電氣有限責(zé)任公司