高玲玲 戴秉秩
(1.合肥學(xué)院 人工智能與大數(shù)據(jù)學(xué)院,安徽 合肥 230023;2.合肥移瑞通信技術(shù)有限公司,安徽 合肥 230088)
DarwIn機器人由于其設(shè)備特點,開發(fā)過程與服務(wù)器開發(fā)類似,基本采用SSH遠程連接方式開發(fā)[1]。但使用SSH遠程連接的方式存在無法在終端中運行圖形化開發(fā)工具的弊端。若采用文本編輯器在終端中運行,又不具有友好的集成開發(fā)環(huán)境。如果在桌面系統(tǒng)進行開發(fā),則需要拷貝源碼,開發(fā)過程十分復(fù)雜。本項目旨在為DarwIn機器人的開發(fā)提供一個友好的、能運行在終端環(huán)境中的集成開發(fā)環(huán)境。在DarwIn機器人開發(fā)過程中,可以采用SSH遠程連接方式開發(fā),也可以在PC端進行開發(fā),本項目需要能夠兼容這兩種方式。
根據(jù)IDE的使用場景及Vim的特點,IDE的總體功能采用模塊化設(shè)計,每個功能模塊之間相互獨立,Vim負責(zé)與用戶進行交互,并與各個模塊通信,如圖1所示。
圖1 IDE軟件框架
2.2.1 文件列表及代碼標簽查看模塊設(shè)計與實現(xiàn)
文件列表查看模塊需要支持文件夾的打開與關(guān)閉,文件的快速打開編輯等功能,該模塊采用分離式設(shè)計,由交互窗口、適配器和運算器三部分組成,其運算器使用Linux標準工具包的ls工具來實現(xiàn)[2]。
代碼標簽查看模塊與文件瀏覽模塊類似。針對不同的語言,存在代碼標簽格式不同的問題,因此,本項目在適配器層面引入二級適配器結(jié)構(gòu)。一級適配器負責(zé)將運算器傳遞的標簽進行簡單處理,并篩選對應(yīng)開發(fā)語言的二級適配器,將處理結(jié)果傳遞給二級適配器;二級適配器根據(jù)一級適配器的篩選結(jié)果,使用對應(yīng)語言的處理模塊,對代碼標簽進行處理,并將處理結(jié)果返回給一級適配器。適配器分級后,可以使原本固定的適配器變成一個可拓展的結(jié)構(gòu)。
一二級適配器的接口使用字典的數(shù)據(jù)結(jié)構(gòu),字典的Key為標簽類型,Value為一個列表,其中包含該類型的所有標簽。采用如下方式實現(xiàn)可擴展框架:(1)維護一個filetype變量,存放需要生成代碼標簽的代碼文件類型;(2)語言適配器統(tǒng)一存放在autoload目錄下,命名均使用“語言對應(yīng)文件類型tags.vim”;(3)語言適配器中提供一個“GenerateTags()”函數(shù),該函數(shù)返回處理后的標簽字典。工作流程,如圖2所示。
圖2 DTag工作流程
2.2.2 C++代碼自動格式化模塊設(shè)計與實現(xiàn)
根據(jù)使用場景,該模塊的結(jié)構(gòu)劃分為句子合成器和詞法分析器。Vim將句子送入詞法分析器,詞法分析器對句子進行分割,并將分割后的詞法單元送入句子合成器[3]。句子合成器按照規(guī)則,向詞法單元中添加空白符。
然而,從代碼分割出詞法單元的過程,實際上是正則表達式匹配的過程。該過程中,有些多字符詞法單元將會被過度分割,如注釋符“//”將被匹配成兩個除法符號。因此,單純地使用正則表達式顯然是無法解決過度分割問題,因此,引入自動機解決被過度分割的運算符重組成新的詞法單元。例如,“//”符號將被詞法分析器識別成“Divide Divide”,為將其修改為“Comment”,在此處添加一個自動機,當符號被該自動機接收時,讀入的符號為“//”,可將其修改為詞法單元“Comment”。
2.2.3 Makefile生成模塊設(shè)計與實現(xiàn)
Gencmake模塊實現(xiàn)遞歸遍歷項目文件夾中的所有代碼文件,并分析其依賴關(guān)系,生成一個中間文件,用戶可以編輯該文件,最后使用第三方工具根據(jù)該中間文件生成Makefile[4]。根據(jù)該操作流程,將Gencmake的框架劃分為代碼分析器和文件檢索器。代碼分析器將代碼所依賴的文件傳遞至文件檢索器,文件檢索器檢索該文件,并將路徑傳遞給代碼分析器,這是一個遞歸的過程。遞歸后Gencmake將能夠檢索出項目的全部依賴關(guān)系,并生成中間文件,但如果依賴項以靜態(tài)鏈接庫的形式存在,則需要用戶自行給出依賴關(guān)系并編輯中間文件。
2.2.4 DarwIn參數(shù)調(diào)節(jié)模塊設(shè)計與實現(xiàn)
由于DarwIn提供了一個可以調(diào)節(jié)參數(shù)的Web服務(wù)器,因此,DarwInSetting模塊的本質(zhì)是一個爬蟲應(yīng)用,通過爬取Web頁面的內(nèi)容來顯示到Vim上,再通過Post方法將修改后的參數(shù)傳遞至DarwIn的Web服務(wù)器,該模塊的框架可以劃分為交互窗口和爬蟲,如圖3所示。
圖 3 DarwInSetting模塊框架
而該模塊工作流程,如圖4所示。
圖4 DarwInSetting工作流程
從正則表達式引擎的角度分析,正則表達式引擎大量使用NFA(非確定有限狀態(tài)自動機)作為解析器,而NFA在執(zhí)行過程中,最影響效率的過程是回溯[5]。正則表達式的優(yōu)化,就是要減少正則NFA解析器在匹配過程中的回溯。
結(jié)合回溯過程和正則表達式的語法特點,在編寫正則表達式時,需要注意以下幾點:
(a)盡量避免多選結(jié)構(gòu)。例如,表達式“a|b|c|d|e|f”與表達式“[a-f]”匹配同樣的字符,但前者將會有六個備用狀態(tài)等待引擎回溯,這必然會造成效率的降低。
(b)提取錨點“^”“$”。例如,表達式“^a|^b”會比表達式“^(a|b)”多出一個備選狀態(tài),但二者的匹配功能是相同的。
(c)盡量避免回溯的時間復(fù)雜度指數(shù)級增長。如“([^/]+)*”,每次匹配都需要判斷字符應(yīng)屬于“+”量詞還是屬于“*”量詞,這樣如果匹配一個長度為10的字符串,這樣需要回溯(2^10)-1次,這種指數(shù)級增長的回溯會極大地降低匹配效率。
(d)從閉包中提取必需元素。如“a+”可以將其提取為“aa*”,這樣可以減少正則式的一個備用狀態(tài)。
(e)減少括號的使用。正則表達式中的元字符“()”會改變匹配的優(yōu)先級,造成回溯現(xiàn)象,減少括號的使用,并減少回溯次數(shù)。
序列檢測自動機匹配各種合適的序列并將其送至合成器,合成器根據(jù)序列的類型向其中添加空格。需要檢測的詞法單元包括注釋、字符串等,自動機模型如圖5、6、7所示。經(jīng)過自動機處理后,原本被過度分割的詞法單元能夠重新組合成新的詞法單元,以保證格式化的正確性。
圖5 用于檢測左塊注釋符的自動機模型
圖6 用以檢測右塊注釋符的自動機模型
圖7 用以檢測字符串的自動機模型
文件列表查看模塊工作情況如圖8所示,代碼標簽瀏覽模塊如圖9所示。
圖8 文件列表查看模塊
圖9 代碼標簽查看模塊
C++語法高亮模塊加載效果如圖10所示。
圖10 加載語法高亮插件前后
C++自動格式化模塊加載效果如圖11所示。
圖11 自動格式化前后
本文借助Vim作為核心組件,使用VimScript和Python語言開發(fā)了一套能夠用于DarwIn機器人開發(fā)工作的集成開發(fā)環(huán)境,應(yīng)用該IDE能使DarwIn機器人的開發(fā)工作變得方便快捷。本文先就系統(tǒng)的可行性和用戶需求進行了詳細的分析,并根據(jù)需求對各個模塊進行了詳細的設(shè)計,同時,介紹了在實現(xiàn)各個模塊時所用到的技術(shù)與原理,最后展示了整個IDE的運行效果,達到了準確和易用的設(shè)計目標。