高玲玲 戴秉秩
(1.合肥學(xué)院 人工智能與大數(shù)據(jù)學(xué)院,安徽 合肥 230023;2.合肥移瑞通信技術(shù)有限公司,安徽 合肥 230088)
DarwIn機(jī)器人由于其設(shè)備特點(diǎn),開(kāi)發(fā)過(guò)程與服務(wù)器開(kāi)發(fā)類似,基本采用SSH遠(yuǎn)程連接方式開(kāi)發(fā)[1]。但使用SSH遠(yuǎn)程連接的方式存在無(wú)法在終端中運(yùn)行圖形化開(kāi)發(fā)工具的弊端。若采用文本編輯器在終端中運(yùn)行,又不具有友好的集成開(kāi)發(fā)環(huán)境。如果在桌面系統(tǒng)進(jìn)行開(kāi)發(fā),則需要拷貝源碼,開(kāi)發(fā)過(guò)程十分復(fù)雜。本項(xiàng)目旨在為DarwIn機(jī)器人的開(kāi)發(fā)提供一個(gè)友好的、能運(yùn)行在終端環(huán)境中的集成開(kāi)發(fā)環(huán)境。在DarwIn機(jī)器人開(kāi)發(fā)過(guò)程中,可以采用SSH遠(yuǎn)程連接方式開(kāi)發(fā),也可以在PC端進(jìn)行開(kāi)發(fā),本項(xiàng)目需要能夠兼容這兩種方式。
根據(jù)IDE的使用場(chǎng)景及Vim的特點(diǎn),IDE的總體功能采用模塊化設(shè)計(jì),每個(gè)功能模塊之間相互獨(dú)立,Vim負(fù)責(zé)與用戶進(jìn)行交互,并與各個(gè)模塊通信,如圖1所示。

圖1 IDE軟件框架
2.2.1 文件列表及代碼標(biāo)簽查看模塊設(shè)計(jì)與實(shí)現(xiàn)
文件列表查看模塊需要支持文件夾的打開(kāi)與關(guān)閉,文件的快速打開(kāi)編輯等功能,該模塊采用分離式設(shè)計(jì),由交互窗口、適配器和運(yùn)算器三部分組成,其運(yùn)算器使用Linux標(biāo)準(zhǔn)工具包的ls工具來(lái)實(shí)現(xiàn)[2]。
代碼標(biāo)簽查看模塊與文件瀏覽模塊類似。針對(duì)不同的語(yǔ)言,存在代碼標(biāo)簽格式不同的問(wèn)題,因此,本項(xiàng)目在適配器層面引入二級(jí)適配器結(jié)構(gòu)。一級(jí)適配器負(fù)責(zé)將運(yùn)算器傳遞的標(biāo)簽進(jìn)行簡(jiǎn)單處理,并篩選對(duì)應(yīng)開(kāi)發(fā)語(yǔ)言的二級(jí)適配器,將處理結(jié)果傳遞給二級(jí)適配器;二級(jí)適配器根據(jù)一級(jí)適配器的篩選結(jié)果,使用對(duì)應(yīng)語(yǔ)言的處理模塊,對(duì)代碼標(biāo)簽進(jìn)行處理,并將處理結(jié)果返回給一級(jí)適配器。適配器分級(jí)后,可以使原本固定的適配器變成一個(gè)可拓展的結(jié)構(gòu)。
一二級(jí)適配器的接口使用字典的數(shù)據(jù)結(jié)構(gòu),字典的Key為標(biāo)簽類型,Value為一個(gè)列表,其中包含該類型的所有標(biāo)簽。采用如下方式實(shí)現(xiàn)可擴(kuò)展框架:(1)維護(hù)一個(gè)filetype變量,存放需要生成代碼標(biāo)簽的代碼文件類型;(2)語(yǔ)言適配器統(tǒng)一存放在autoload目錄下,命名均使用“語(yǔ)言對(duì)應(yīng)文件類型tags.vim”;(3)語(yǔ)言適配器中提供一個(gè)“GenerateTags()”函數(shù),該函數(shù)返回處理后的標(biāo)簽字典。工作流程,如圖2所示。

圖2 DTag工作流程
2.2.2 C++代碼自動(dòng)格式化模塊設(shè)計(jì)與實(shí)現(xiàn)
根據(jù)使用場(chǎng)景,該模塊的結(jié)構(gòu)劃分為句子合成器和詞法分析器。Vim將句子送入詞法分析器,詞法分析器對(duì)句子進(jìn)行分割,并將分割后的詞法單元送入句子合成器[3]。句子合成器按照規(guī)則,向詞法單元中添加空白符。
然而,從代碼分割出詞法單元的過(guò)程,實(shí)際上是正則表達(dá)式匹配的過(guò)程。該過(guò)程中,有些多字符詞法單元將會(huì)被過(guò)度分割,如注釋符“//”將被匹配成兩個(gè)除法符號(hào)。因此,單純地使用正則表達(dá)式顯然是無(wú)法解決過(guò)度分割問(wèn)題,因此,引入自動(dòng)機(jī)解決被過(guò)度分割的運(yùn)算符重組成新的詞法單元。例如,“//”符號(hào)將被詞法分析器識(shí)別成“Divide Divide”,為將其修改為“Comment”,在此處添加一個(gè)自動(dòng)機(jī),當(dāng)符號(hào)被該自動(dòng)機(jī)接收時(shí),讀入的符號(hào)為“//”,可將其修改為詞法單元“Comment”。
2.2.3 Makefile生成模塊設(shè)計(jì)與實(shí)現(xiàn)
Gencmake模塊實(shí)現(xiàn)遞歸遍歷項(xiàng)目文件夾中的所有代碼文件,并分析其依賴關(guān)系,生成一個(gè)中間文件,用戶可以編輯該文件,最后使用第三方工具根據(jù)該中間文件生成Makefile[4]。根據(jù)該操作流程,將Gencmake的框架劃分為代碼分析器和文件檢索器。代碼分析器將代碼所依賴的文件傳遞至文件檢索器,文件檢索器檢索該文件,并將路徑傳遞給代碼分析器,這是一個(gè)遞歸的過(guò)程。遞歸后Gencmake將能夠檢索出項(xiàng)目的全部依賴關(guān)系,并生成中間文件,但如果依賴項(xiàng)以靜態(tài)鏈接庫(kù)的形式存在,則需要用戶自行給出依賴關(guān)系并編輯中間文件。
2.2.4 DarwIn參數(shù)調(diào)節(jié)模塊設(shè)計(jì)與實(shí)現(xiàn)
由于DarwIn提供了一個(gè)可以調(diào)節(jié)參數(shù)的Web服務(wù)器,因此,DarwInSetting模塊的本質(zhì)是一個(gè)爬蟲(chóng)應(yīng)用,通過(guò)爬取Web頁(yè)面的內(nèi)容來(lái)顯示到Vim上,再通過(guò)Post方法將修改后的參數(shù)傳遞至DarwIn的Web服務(wù)器,該模塊的框架可以劃分為交互窗口和爬蟲(chóng),如圖3所示。

圖 3 DarwInSetting模塊框架
而該模塊工作流程,如圖4所示。

圖4 DarwInSetting工作流程
從正則表達(dá)式引擎的角度分析,正則表達(dá)式引擎大量使用NFA(非確定有限狀態(tài)自動(dòng)機(jī))作為解析器,而NFA在執(zhí)行過(guò)程中,最影響效率的過(guò)程是回溯[5]。正則表達(dá)式的優(yōu)化,就是要減少正則NFA解析器在匹配過(guò)程中的回溯。
結(jié)合回溯過(guò)程和正則表達(dá)式的語(yǔ)法特點(diǎn),在編寫正則表達(dá)式時(shí),需要注意以下幾點(diǎn):
(a)盡量避免多選結(jié)構(gòu)。例如,表達(dá)式“a|b|c|d|e|f”與表達(dá)式“[a-f]”匹配同樣的字符,但前者將會(huì)有六個(gè)備用狀態(tài)等待引擎回溯,這必然會(huì)造成效率的降低。
(b)提取錨點(diǎn)“^”“$”。例如,表達(dá)式“^a|^b”會(huì)比表達(dá)式“^(a|b)”多出一個(gè)備選狀態(tài),但二者的匹配功能是相同的。
(c)盡量避免回溯的時(shí)間復(fù)雜度指數(shù)級(jí)增長(zhǎng)。如“([^/]+)*”,每次匹配都需要判斷字符應(yīng)屬于“+”量詞還是屬于“*”量詞,這樣如果匹配一個(gè)長(zhǎng)度為10的字符串,這樣需要回溯(2^10)-1次,這種指數(shù)級(jí)增長(zhǎng)的回溯會(huì)極大地降低匹配效率。
(d)從閉包中提取必需元素。如“a+”可以將其提取為“aa*”,這樣可以減少正則式的一個(gè)備用狀態(tài)。
(e)減少括號(hào)的使用。正則表達(dá)式中的元字符“()”會(huì)改變匹配的優(yōu)先級(jí),造成回溯現(xiàn)象,減少括號(hào)的使用,并減少回溯次數(shù)。
序列檢測(cè)自動(dòng)機(jī)匹配各種合適的序列并將其送至合成器,合成器根據(jù)序列的類型向其中添加空格。需要檢測(cè)的詞法單元包括注釋、字符串等,自動(dòng)機(jī)模型如圖5、6、7所示。經(jīng)過(guò)自動(dòng)機(jī)處理后,原本被過(guò)度分割的詞法單元能夠重新組合成新的詞法單元,以保證格式化的正確性。

圖5 用于檢測(cè)左塊注釋符的自動(dòng)機(jī)模型

圖6 用以檢測(cè)右塊注釋符的自動(dòng)機(jī)模型

圖7 用以檢測(cè)字符串的自動(dòng)機(jī)模型
文件列表查看模塊工作情況如圖8所示,代碼標(biāo)簽瀏覽模塊如圖9所示。

圖8 文件列表查看模塊

圖9 代碼標(biāo)簽查看模塊
C++語(yǔ)法高亮模塊加載效果如圖10所示。

圖10 加載語(yǔ)法高亮插件前后
C++自動(dòng)格式化模塊加載效果如圖11所示。

圖11 自動(dòng)格式化前后
本文借助Vim作為核心組件,使用VimScript和Python語(yǔ)言開(kāi)發(fā)了一套能夠用于DarwIn機(jī)器人開(kāi)發(fā)工作的集成開(kāi)發(fā)環(huán)境,應(yīng)用該IDE能使DarwIn機(jī)器人的開(kāi)發(fā)工作變得方便快捷。本文先就系統(tǒng)的可行性和用戶需求進(jìn)行了詳細(xì)的分析,并根據(jù)需求對(duì)各個(gè)模塊進(jìn)行了詳細(xì)的設(shè)計(jì),同時(shí),介紹了在實(shí)現(xiàn)各個(gè)模塊時(shí)所用到的技術(shù)與原理,最后展示了整個(gè)IDE的運(yùn)行效果,達(dá)到了準(zhǔn)確和易用的設(shè)計(jì)目標(biāo)。