張 宇,王 珂,劉樂云
(上海廣播電視衛(wèi)星地球站,上海 201114)
計算機編譯原理在開發(fā)工具中是作為基礎(chǔ)進行實現(xiàn)的,可在常見的應用場景下很少被采用。主要原因是有以下幾點:一是,應用程序的實現(xiàn)主要是與用戶接觸,更多與自然語言以及自然行為有關(guān),更偏向于模糊與概率,所以人工智能在這方向應用的比較多也更合適。但在與設(shè)備通訊時,對于參數(shù)的判定要求真實,不存在模棱兩可的情況。因此,我們在開發(fā)這方面的程序時,會使用判定語句、條件語句和一些運算來計算出報警情況,在效率、安全和開發(fā)難度的綜合考慮下,我們會在程序中固化這些策略。但在長期的使用中發(fā)現(xiàn),因為涉及的參數(shù)比較多,如果出現(xiàn)判斷策略的改變,這將導致較大的程序升級,升級就意味了測試與成本。為了提高維護效率以及避免這種情況的更新需求,通過對報警策略進行解釋表達式的方式進行開發(fā),變得非常有價值。用戶只需要在程序里修改報警表達式,就可以滿足所有的報警策略方面的軟件升級。
在設(shè)備監(jiān)控中,常見的參數(shù)報警策略有以下一項或多項的與或組合:
⊙ 大于參考值。
⊙ 小于參考值。
⊙ 等于參考值。
⊙ 不等于參考值。
⊙ 在范圍內(nèi)(包括范圍)。
⊙ 在范圍外(包括范圍)。
⊙ 枚舉參數(shù)值。
在設(shè)備監(jiān)控中,常見的參數(shù)報警策略可能用到的數(shù)據(jù)類型:
⊙ 整形。
⊙ 浮點數(shù)。
⊙ 布爾數(shù)。
⊙ 字符串。
⊙ 時間。
⊙ ……
例如:當需要制定溫濕度報警時,我們可能寫入如下策略:
設(shè)定室內(nèi)溫度24℃為參考溫度,當溫度高于等于參考值2℃(26℃)時進行警告,當溫度低于等于參考值2℃(22℃)時進行警告,當溫度高于等于4℃(28℃)時報警,當溫度低于等于4℃(20℃)時進行報警。
else Normal();//溫度正常這樣的表達式對于一般的程序員來說沒有問題,但這些語句必須被寫入程序,當參考值由24調(diào)整為25時,我們的程序可能需要做一些調(diào)整,將所有的上下限做相應的加1修改就可以了。但當這樣的調(diào)整很頻繁時,我們不得不修改程序的結(jié)構(gòu),將參考值、當前值、警告時范圍、報警時范圍都考慮在內(nèi),這樣將來再需要調(diào)整這些參考值時,就不再需要修改程序,只需要修改相關(guān)的參數(shù)就可以了。不過當上下限范圍發(fā)生變化或需要更多的報警級別時,修改相應的程序結(jié)構(gòu)將變得非常復雜,更何況在設(shè)備監(jiān)控中需要采集的數(shù)據(jù)類型種類眾多,對于程序開發(fā)和后期維護是非常不利的。在這樣的背景下,通過表達式編譯方式的程序開發(fā)結(jié)構(gòu)被提出。
通過對眾多參數(shù)策略的羅列與比對,我們對報警策略表達式的抽象結(jié)構(gòu)做了以下幾點的總結(jié):
⊙ 參考值的上下限范圍,上下范圍可能相同或不同,極限情況下范圍為0。
⊙ 周期內(nèi)的持續(xù)變化,可能是連續(xù)上升、下降,極端情況下可能是不變化。
⊙ 區(qū)分報警等級,也就是計算出數(shù)值,由數(shù)值對應報警的形式(顏色、聲音和操作)。
表達式編譯算法的目的:能夠理解表達式的意圖,全面真實的反應表達式結(jié)構(gòu),能對每一個范疇內(nèi)的運算符進行運算,最終產(chǎn)生正確的結(jié)果,并將結(jié)果以數(shù)值形式展現(xiàn)出來。
首先,表達式是由數(shù)字、算符、數(shù)字分組符號(括號)、自由變量和約束變量等以能求得數(shù)值的有意義排列方法所得的組合。也就是說,表達式能夠被一般人理解的可見算式。
如 :((@+2)<$)?l1 :l0 ;
表達式的含義為:當前值+2小于參考值時返回長整形1否則返回長整形0;表達式運算符的關(guān)鍵字如表1中定義。
表1
運算符優(yōu)先級定義如表2。
表2
數(shù)據(jù)類型定義如表3。
表3
我們就以((@+2)<$)?1l:0l;為例對表達式的轉(zhuǎn)換與計算做簡單的算法介紹:
(1)以下每個步驟,逐一處理每個字符。
(2)首先創(chuàng)建一個根表達式R。
(3)當讀到第1個左括號,創(chuàng)建表達式E0,將”(”寫入左目,連接到根結(jié)構(gòu)R的左目之下。
(4)讀到第2個左括號,再創(chuàng)建表達式E1,將”(”寫入左目,連接到表達式E0的左目之下。
(5)讀到 @,因為是變量,再次創(chuàng)建樹狀表達式E2,將”@”寫入左目,連接到E1左目之下。
(6)讀到+,因為是運算符,將直接寫入E2的操作符中。
(7)讀到2,因為是常數(shù),將直接寫入E2的右目,E2表達式完成,回溯到E1。
(8)讀到),表示掛號完整,等待后續(xù)。
(9)讀到<,因為是運算符,將直接寫入表達式E1的操作符中。
(10)讀到$,將直接寫入表達式E1右目,回溯到表達式E0。
(11)讀到?,因為是運算符,直接寫入操作符中。
(12)讀到1l,表示輸出數(shù)據(jù)類型為長整形,寫入右目。
(13)讀到,表示確定操作符為條件語句,等待第三目。
(14)讀到0l,表示輸出數(shù)據(jù)類型為長整形,寫入第三目。
(15)讀到;表示表達式結(jié)束,回溯到R。
(16)退出表達式構(gòu)造。
產(chǎn)生的表達式樹狀結(jié)構(gòu)如圖1所示。
圖1
對產(chǎn)生的樹狀結(jié)構(gòu)進行計算:
(1)得到R。
(2)獲取E0左目。
(3)獲取E1左目。
(4)獲取E2左目@與E2右目相加,得到結(jié)果@1回溯到E1。
(5)將@1與$做比對,獲取結(jié)果TF,回溯到E0。
(6)如果TF=T,獲取結(jié)果1,否則獲取結(jié)果0,回溯到R。
(7)由R產(chǎn)生結(jié)果輸出。
對于每一種輸出的值,只要在數(shù)據(jù)庫中對該參數(shù)做好相應的定義,如:字體顯示顏色、報警的聲音、操作行為等,就可以從展現(xiàn)角度視為不同的報警級別。如圖2所示。
圖2
修改程序構(gòu)架的時候擔心的運行效率問題并沒有成為瓶頸,解釋程序?qū)Γǎˊ+2)<$)?1l:0l;這樣的表達式在普通PC上進行10億次的運算消耗的時間小于1秒。表達式解釋程序在應用場景中可滿足日常的設(shè)備監(jiān)控的需要,并已在多個項目中廣泛使用。真正做到無需修改程序就可滿足參數(shù)添加和不同種類的報警策略的修改與設(shè)定。
[1] (美)阿霍(Aho,A,V)等著.李建中等譯.編譯原理.北京:機械工業(yè)出版社.