李勇
(中國(guó)人民解放軍92941部隊(duì)96分隊(duì),遼寧 葫蘆島 125001)
摘要:GIS(地理信息系統(tǒng))是個(gè)復(fù)雜的系統(tǒng),在主要功能一致的前提下,如何為用戶提供專用的系統(tǒng)是迫切需要解決的問(wèn)題。腳本技術(shù)以其靈活的可定制性和可擴(kuò)展性的優(yōu)勢(shì)解決了此問(wèn)題。研究了基于腳本引擎的開(kāi)發(fā)技術(shù),分析了基于腳本引擎的GIS結(jié)構(gòu),設(shè)計(jì)并實(shí)現(xiàn)了腳本引擎。
關(guān)鍵詞:3d GIS;腳本引擎;Lub;狀態(tài)轉(zhuǎn)換;虛擬機(jī)API
中圖分類號(hào):TP319文獻(xiàn)標(biāo)識(shí)碼:ADOI: 10.19358/j.issn.1674-7720.2017.10.007
引用格式:李勇.腳本引擎在三維GIS系統(tǒng)中的設(shè)計(jì)與實(shí)現(xiàn)[J].微型機(jī)與應(yīng)用,2017,36(10):23-25,29.
0引言
隨著計(jì)算機(jī)技術(shù)的不斷發(fā)展,計(jì)算機(jī)編程語(yǔ)言和技術(shù)都發(fā)生了很大變化。在傳統(tǒng)的工程應(yīng)用系統(tǒng)的設(shè)計(jì)中,軟件往往在實(shí)現(xiàn)之前用戶需求就發(fā)生變更。因此,人們迫切需要開(kāi)發(fā)出可定制化、可用戶化和可擴(kuò)展的軟件系統(tǒng)來(lái)減少需求變更所帶來(lái)的開(kāi)發(fā)和維護(hù)成本[1]。
使用基于混合腳本編程的方法是實(shí)現(xiàn)擴(kuò)展靈活的可定制軟件系統(tǒng)的有效方法。近年來(lái),腳本語(yǔ)言憑借其強(qiáng)大的描述能力和靈活的語(yǔ)法結(jié)構(gòu),為應(yīng)用程序提供腳本支持,從而進(jìn)行混合語(yǔ)言開(kāi)發(fā)被,成為實(shí)現(xiàn)可擴(kuò)展和可定制的有效方案[2]。目前,腳本語(yǔ)言已經(jīng)廣泛應(yīng)用于計(jì)算機(jī)軟件領(lǐng)域,如JavaScrip應(yīng)用于Web網(wǎng)頁(yè)設(shè)計(jì)、微軟的VBA用于Office應(yīng)用的自動(dòng)化以及開(kāi)源領(lǐng)域中Ruby、Python、Jython等腳本語(yǔ)言[3]。
本文主要關(guān)注在三維GIS系統(tǒng)中,如何實(shí)現(xiàn)可定制、可擴(kuò)展功能的腳本引擎,來(lái)滿足用戶的多元化需求。
1腳本引擎關(guān)鍵技術(shù)分析
1.1腳本語(yǔ)言簡(jiǎn)介
腳本語(yǔ)言是為了縮短傳統(tǒng)的編寫(xiě)-編譯-鏈接-運(yùn)行過(guò)程而創(chuàng)建的計(jì)算機(jī)編程語(yǔ)言,用來(lái)控制應(yīng)用程序,具有良好的快速開(kāi)發(fā)能力和與其他語(yǔ)言編寫(xiě)的程序組件之間通信的功能[4]。很多腳本語(yǔ)言用來(lái)執(zhí)行一次性任務(wù),尤其是系統(tǒng)管理方面,它可以把服務(wù)組件粘合起來(lái),廣泛用于GUI創(chuàng)建或者命令行。腳本通常以文本保存,只在被調(diào)用時(shí)進(jìn)行解釋或編譯,經(jīng)常把腳本和其他低級(jí)編程語(yǔ)言一起使用,各自發(fā)揮優(yōu)勢(shì)解決特定問(wèn)題[5]。
1.2腳本引擎技術(shù)分析
在腳本運(yùn)行過(guò)程中,腳本引擎先將腳本解釋為中間指令,再執(zhí)行中間指令,所以腳本引擎既是腳本解釋器又是腳本執(zhí)行器[6]。此外,嵌入腳本引擎、支持腳本語(yǔ)言的應(yīng)用程序稱為主程序[7]。腳本引擎、腳本程序與主程序之間的關(guān)系如圖1所示。腳本程序是用戶事先編寫(xiě)完的字符串,可以保存到文本文件或特定格式文件中,能被腳本引擎識(shí)別;當(dāng)需要執(zhí)行某個(gè)腳本程序時(shí),主程序通過(guò)調(diào)用腳本引擎API來(lái)啟動(dòng)腳本引擎和通知腳本引擎執(zhí)行此腳本程序;腳本引擎加載、解釋、
運(yùn)行腳本程序,并將結(jié)果反饋給主程序??梢?jiàn),腳本引擎是主程序和腳本程序的紐帶。
2腳本引擎在三維GIS系統(tǒng)中的結(jié)構(gòu)分析
三維GIS是模擬、表示、管理、分析客觀世界中的三維空間實(shí)體及其相關(guān)信息的計(jì)算機(jī)系統(tǒng),能為管理和決策提供更加直接和真實(shí)的目標(biāo)和研究對(duì)象。為提高系統(tǒng)的穩(wěn)定性和可移植性,在設(shè)計(jì)系統(tǒng)結(jié)構(gòu)時(shí)采用先進(jìn)的NTIER架構(gòu)。系統(tǒng)軟件部分采用面向?qū)ο蟮脑O(shè)計(jì)方法以及基于組件設(shè)計(jì)的理念和技術(shù),從縱向的架構(gòu)層面上,該系統(tǒng)提供三大層面、若干小層面的抽象、映射、實(shí)現(xiàn)和封裝;應(yīng)用層對(duì)各子系統(tǒng)的用戶業(yè)務(wù)處理邏輯進(jìn)行實(shí)現(xiàn)和封裝,數(shù)據(jù)庫(kù)層是采用多種形式結(jié)構(gòu)數(shù)據(jù)庫(kù)的總體封裝,提供本地及遠(yuǎn)程多種數(shù)據(jù)連接方式,為應(yīng)用層提供透明的數(shù)據(jù)存儲(chǔ)和訪問(wèn)功能。GIS系統(tǒng)層次結(jié)構(gòu)如圖2所示。
如圖2所示,該系統(tǒng)基于空間GIS數(shù)據(jù)庫(kù)和各類專用數(shù)據(jù)庫(kù),運(yùn)用VR技術(shù),通過(guò)使用三維引擎及腳本引擎,實(shí)現(xiàn)三維地景瀏覽、空間定位查看、空間量測(cè)等豐富功能。腳本引擎模塊處于中間層,向下管理著各種專用數(shù)據(jù)庫(kù)數(shù)據(jù);同層中,可調(diào)用三維引擎模塊,從而控制三維場(chǎng)景和模型的顯示方式;向上提供本模塊的調(diào)用接口,供應(yīng)用層調(diào)用,完成資源的控制。
3腳本引擎總體結(jié)構(gòu)設(shè)計(jì)
腳本引擎模塊結(jié)構(gòu)為上下兩層。上層能識(shí)別腳本語(yǔ)言,并將腳本程序編譯成字節(jié)碼指令;下層執(zhí)行字節(jié)碼指令。上下層的分離可以提高腳本引擎的可移植性和可擴(kuò)展性。如圖3所示,上層編譯器負(fù)責(zé)將腳本源程序的字節(jié)流轉(zhuǎn)換成指令序列,對(duì)源程序進(jìn)行詞法、語(yǔ)法等進(jìn)行邏輯分析,當(dāng)出現(xiàn)錯(cuò)誤時(shí)給出錯(cuò)誤圖3腳本引擎體系結(jié)構(gòu)信息和定位錯(cuò)位位置;虛擬機(jī)負(fù)責(zé)指令流的解釋執(zhí)行;API是虛擬機(jī)與主程序交互的橋梁,實(shí)現(xiàn)兩者之間互相控制、通信。
4腳本引擎設(shè)計(jì)與實(shí)現(xiàn)
本腳本引擎面向的腳本語(yǔ)言為自主設(shè)計(jì)的語(yǔ)言Lub。Lub語(yǔ)法符合LL(1)型文法,可以采用自頂向下遞歸法進(jìn)行語(yǔ)法解析。
4.1詞法分析器設(shè)計(jì)與實(shí)現(xiàn)
Lub腳本語(yǔ)言的詞法標(biāo)記有四類:標(biāo)識(shí)符、關(guān)鍵字、常量、特殊符號(hào)。標(biāo)識(shí)符用來(lái)標(biāo)識(shí)腳本程序中的變量、數(shù)組和函數(shù),由字母、數(shù)字和下劃線組成,且標(biāo)識(shí)符首字母不能是數(shù)字;關(guān)鍵字是能夠被詞法分析器識(shí)別的具有特定含義的字符串,如定義變量的關(guān)鍵字、運(yùn)算符號(hào)、判斷符號(hào)、控制符號(hào)等;常量指數(shù)字和字符串;特殊符號(hào)包含注釋符、轉(zhuǎn)義符。
詞法分析器負(fù)責(zé)將輸入的源程序按照構(gòu)詞規(guī)則分解成一系列單詞符號(hào),功能可細(xì)分如下:輸入、預(yù)處理功能、超前搜索功能、狀態(tài)轉(zhuǎn)換功能。詞法分析器工作的第一步是輸入源程序文本,為了更好地對(duì)單詞符號(hào)識(shí)別,對(duì)輸入串先進(jìn)行預(yù)處理,主要是過(guò)濾掉空格、注釋、換行符等;在詞法分析過(guò)程中,為了能確定詞性,需要超前搜索若干字符;詞法分析器使用狀態(tài)轉(zhuǎn)換圖來(lái)識(shí)別單詞符號(hào)。
4.1.1狀態(tài)轉(zhuǎn)換圖實(shí)現(xiàn)
狀態(tài)轉(zhuǎn)換圖是一張有限方向圖。在狀態(tài)轉(zhuǎn)換圖中,有一個(gè)初態(tài),至少一個(gè)終態(tài)。輸入的字符信息進(jìn)入狀態(tài)轉(zhuǎn)換圖的初始狀態(tài),最終會(huì)經(jīng)過(guò)一條路徑到達(dá)某個(gè)終結(jié)狀態(tài),并得到其識(shí)別的字符串。下面給出注釋的狀態(tài)轉(zhuǎn)換圖,注釋格式:/* 注釋部分*/,轉(zhuǎn)換圖如圖4所示。
每讀入一個(gè)字符,如果字符是“/”,就說(shuō)明后面的部分可能是注釋,再看下一個(gè)輸入字符,如果是“*”, 就是注釋中的“ /*”,那么后面的部分就是注釋部分,然后再用相同的方法找出"*/",對(duì)應(yīng)的邏輯實(shí)現(xiàn)代碼如下:
while((ch=getchar())!=EOF)
switch(state)
case 1 :if ch=="/",state=2,break;
case 2:if ch=="*",state=3
else state=1;break;
case 3:if ch=="*",state=4;
else state=3;break;
case 4: if ch=="/",state=5;
else state=3;break;
case 5:……
4.1.2待分析的詞法及類別碼
腳本引擎支持16個(gè)關(guān)鍵字、5種控制語(yǔ)句和常見(jiàn)運(yùn)算符,每個(gè)單詞符號(hào)都有對(duì)應(yīng)的類別碼,見(jiàn)表1。
表1主要關(guān)鍵字對(duì)應(yīng)的類別碼
詞法分析過(guò)程中會(huì)分析所有單詞,并獲得其類別碼,其實(shí)現(xiàn)函數(shù)定義如下:
Void gettypecode(INT char* string ,OUT BYTE syn,OUT char*toke);
輸入:待分析的源程序字符串。
輸出:syn為單詞類別碼,token為存放的單詞本身字符串。
4.2語(yǔ)法分析器設(shè)計(jì)與實(shí)現(xiàn)
語(yǔ)法分析器的作用是將詞法分析輸出的單詞序列作為輸入,根據(jù)語(yǔ)言的文法規(guī)則,生成中間代碼,語(yǔ)法分析遇到錯(cuò)誤時(shí)會(huì)定位錯(cuò)誤位置,以便糾錯(cuò)。本文采用遞歸下降法實(shí)現(xiàn)語(yǔ)法分析。
遞歸下降分析法要求是LL(1)文法,其基本思想是對(duì)文法中的每個(gè)非終結(jié)符編寫(xiě)一個(gè)函數(shù),再利用函數(shù)之間的遞歸調(diào)用模擬語(yǔ)法樹(shù)自上而下的構(gòu)造過(guò)程,具體實(shí)現(xiàn)方法概述如下:
?。?)每個(gè)非終結(jié)符對(duì)應(yīng)一個(gè)解析函數(shù);
?。?)產(chǎn)生式右側(cè)為該產(chǎn)生式左側(cè)非終結(jié)符所對(duì)應(yīng)解析函數(shù)的“函數(shù)體”;
(3)產(chǎn)生式右側(cè)終結(jié)符對(duì)應(yīng)從輸入串中“消耗”該終結(jié)符的操作;
?。?)產(chǎn)生式中的‘|’對(duì)應(yīng)函數(shù)體中的“ifelse”語(yǔ)句。
對(duì)應(yīng)的邏輯實(shí)現(xiàn)主要結(jié)構(gòu)和函數(shù)如下:
typedef struct LEX
{
Token read;
struct LEX *next;
size_t line;
}MYLEX;//詞法分析得到的所有字符串集合
MYLEX* Read_file(MYLEX* current);
MYLEX* Advance(MYLEX* current); //單詞
int match(Token read ,Token aim);
int Execute_statement(void) //執(zhí)行語(yǔ)句
4.3虛擬機(jī)及接口的設(shè)計(jì)與實(shí)現(xiàn)
虛擬機(jī)模擬運(yùn)行環(huán)境,執(zhí)行字節(jié)碼,并對(duì)腳本得出相應(yīng)的結(jié)果。本文的虛擬機(jī)是堆棧結(jié)構(gòu)的,包括模擬處理器、寄存器和堆棧結(jié)構(gòu)。作為三維顯示系統(tǒng)的一個(gè)輔助功能模塊,虛擬機(jī)需要與三維顯示系統(tǒng)相互調(diào)用,它是腳本引擎與三維顯示系統(tǒng)之間交互的平臺(tái)。其功能包括:初始化主要的數(shù)據(jù)結(jié)構(gòu);指令系統(tǒng)設(shè)計(jì);虛擬機(jī)API設(shè)計(jì)。
4.3.1虛擬機(jī)主要結(jié)構(gòu)
為了模擬CPU、寄存器等真實(shí)的運(yùn)行環(huán)境,虛擬機(jī)必須包含與這些單元對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu),并需要指令執(zhí)行所需要的結(jié)構(gòu)。
指令流:獲取從語(yǔ)法分析器輸出的中間碼,是需要執(zhí)行指令的集合。
程序計(jì)數(shù)器pc:指向下一個(gè)需要執(zhí)行指令的指針。
堆棧:存放重要數(shù)據(jù)的存放地址,支持系統(tǒng)調(diào)用。
4.3.2虛擬機(jī)指令系統(tǒng)
虛擬機(jī)指令系統(tǒng)是以堆棧為中心設(shè)計(jì)的,避免了傳統(tǒng)的以寄存器為中心的限制。與硬件平臺(tái)的無(wú)關(guān)性使得虛擬機(jī)具有良好的跨平臺(tái)性。
每條指令以字節(jié)為單位,模擬處理器執(zhí)行指令。不同的指令對(duì)應(yīng)的操作數(shù)個(gè)數(shù)也不同。獲取字節(jié)后,根據(jù)字節(jié)碼確定其是指令還是數(shù)據(jù),若是指令則判斷對(duì)應(yīng)的操作數(shù)個(gè)數(shù)。由于采用堆棧方式,指令需要的參數(shù)都存放在堆棧中。主要的指令如下:
POP_LUB:堆棧棧頂出棧指令,沒(méi)有操作數(shù)。
PUSH_LUB:數(shù)據(jù)進(jìn)棧指令,有1個(gè)操作數(shù)。
GETNUM_LUB:為參數(shù)分配內(nèi)存空間指令,有1個(gè)操作數(shù)。
CALL_LUB:函數(shù)調(diào)用指令。
RET_LUB:函數(shù)返回指令。
根據(jù)功能,指令可分為三類:數(shù)據(jù)傳輸指令,包括進(jìn)棧、出棧、變量?jī)?nèi)存空間分配等指令;運(yùn)算指令,包括算術(shù)運(yùn)算、邏輯運(yùn)算和字符串運(yùn)算指令;轉(zhuǎn)移指令,包括函數(shù)調(diào)用、返回、條件轉(zhuǎn)移等指令。
4.3.3腳本引擎API設(shè)計(jì)與實(shí)現(xiàn)
腳本引擎API是腳本引擎與主程序交互的窗口,負(fù)責(zé)兩者之間的通信。在三維顯示系統(tǒng)運(yùn)行過(guò)程中,腳本引擎以動(dòng)態(tài)庫(kù)的形式加載到主程序中,腳本引擎可以調(diào)用主程序中的全局變量、函數(shù),實(shí)現(xiàn)對(duì)實(shí)例的訪問(wèn)和調(diào)用。按照功能可將API劃分為三類。
(1)基礎(chǔ)信息管理類
用于進(jìn)行全系統(tǒng)的基礎(chǔ)信息的配置維護(hù),包括二維GIS數(shù)據(jù)的轉(zhuǎn)換和管理模塊,三維地景數(shù)據(jù)的轉(zhuǎn)換、管理和設(shè)置,主要API如下:
void CreateEntity (Str Name,Str Type,Str 2DFileName,Str 3DFileName);//為GIS創(chuàng)建物體
void loadearth(FLOAT[3] Pos, FLOAT[3] Pose);
//加載某個(gè)地景
void PlayCartoon(STR entityName, STR actionName, BOOL bRecycle);//加載視頻流
voidEntityStartMove (STR Name, STR AirwayName,FLOAT Speed);//模擬運(yùn)動(dòng)物體
?。?)場(chǎng)景模擬類
用于模擬真實(shí)的世界場(chǎng)景,包括氣象天氣的模擬。主要API如下:
Void Rain_SetPara(INT RainAccount,DWORD UpColor,DWORD DownColor,INT RainCourse,INT RainAlpha);//模擬下雨效果
VoidSunshine_SetPara (FLOAT NorthAngle, FLOAT EastAngle);//模擬太陽(yáng)效果
VOID SetCameraPosAndPose (FLOAT[3]Pos, FLOAT[3]
Pose);//設(shè)置相機(jī)參數(shù),模擬從某個(gè)位置和角度觀察世界的效果。
(3)方案管理類
主要用于制作有特定需求的顯示方案,主要API如下:
bool SkyLine_Create(STR Name);
void SkyLine_AddPoint(STR Name,FLOAT[3] Pos,INT time);
void CurveCreate (STR Name,INT Width,INT Color);
5結(jié)論
為了提升GIS系統(tǒng)的可定制性,本文提出了基于腳本引擎的GIS系統(tǒng)設(shè)計(jì)思路,利用腳本技術(shù)將各個(gè)基礎(chǔ)功能模塊有效地組合起來(lái),為用戶提供了二次開(kāi)發(fā)的功能。
參考文獻(xiàn)
?。?] 謝斌,高揚(yáng).基于腳本語(yǔ)言的三維動(dòng)畫(huà)技術(shù)的研究與實(shí)現(xiàn)[D].成都:四川師范大學(xué),2007.
?。?] 吳文輝. 輕量級(jí)鍵盤(pán)鼠標(biāo)模擬腳本引擎實(shí)現(xiàn)[J].軟件,2013,34(8):56-57.
?。?] 高明.基于Java平臺(tái)的通用腳本引擎的研究與實(shí)現(xiàn)[D].北京: 北京郵電工大學(xué),2007.
?。?] 王朗.基于虛擬機(jī)的腳本引擎的研究與實(shí)現(xiàn)[D].長(zhǎng)春: 吉林大學(xué),2005.
[5] 謝錦春.基于腳本的三維場(chǎng)景合成和驗(yàn)證系統(tǒng)[D] .杭州:浙江大學(xué),2013.
?。?] 諶勇.游戲腳本引擎設(shè)計(jì)與實(shí)現(xiàn) [D].昆明:昆明理工大學(xué),2007.
?。?] 符盛寶.輕型腳本引擎的研究與開(kāi)發(fā) [D].北京:北京化工大學(xué),2011.