張 慶, 管錦亮
(安徽建筑大學 網絡信息中心, 合肥 230022)
在程序設計教學中,學生不僅要掌握程序靜態結構,還要理解程序執行的動態過程。如果機械地學習一門語言的語法和規范,學生很難形成“將實際問題抽象成程序代碼”的計算思維能力??梢暬虒W方法通過為學生提供直觀的模型圖,簡化了對程序算法的理解,極大提高教學效率。
然而目前缺少一款高效的、可交互的可視化教學的輔助工具軟件,使得在進行可視化教學時大多采用PPT、Flash等工具來描述模型圖,而這些工具不支持將“模型圖”轉換到“代碼”的功能,也不具備交互性特性。桌面應用RAPTOR是一款可交互的可視化教學工具[1-4],但存在編程模型不易發布共享的問題,限制了在師生間溝通和討論問題的效果。
本文探討設計和實現HTML5架構的可視化教學平臺的方法,講解如何實現流程圖模型的繪制展示,描述如何構建解析模型并生成代碼等的功能模塊,詳細給出開發平臺過程中涉及的相關技術和方法。
HTML5的Canvas是非常實用的繪圖控件,用戶不僅可以在Canvas畫布上繪制各種圖形,也可以制作絢麗的動畫。在頁面中添加一個〈canvas〉標簽,即可提供一個強大繪圖區域[5-6]。流程圖是可視化教學中最常用的算法模型,是由節點和連線構成。Canvas中的context封裝了很多繪圖功能的對象,通過調用fillRect、lineTo方法,可以方便地繪制出節點和線條,實現流程圖模型的繪制。HTML5可現強大的動畫效果,通過Canvas結合js的方式模擬出程序執行的動態效果。
JSON是一種輕量級的數據交換格式,為純文本格式,支持嵌套結構與數組。相比與XML,JSON描述數據模型時,具有數據格式簡單、易于讀寫和解析、支持多種語言、占用帶寬低、傳輸效率高的優點。可視化教學平臺需要利用JSON描述并持久化保存流程圖模型中節點和連線的關系,轉換為有向圖的形式,并最終通過解析成為指定語言的源代碼(注: 以解析為C語言的源代碼實例)。
在生成源代碼后,GCC命令可直接編譯、匯編、鏈接出可執行程序。執行程序時,Java的Runtime類可將操作系統下的命令封裝為JVM下的進程,在Web服務中加載Servlet,并與頁面中的WebSocket類通信,將程序編譯和執行時的輸入和輸出信息與基于Web頁面的前臺程序關聯起來。本文將詳細討論如何用Runtime類,將編譯、執行環境封裝為可與Web平臺交互的進程,以及如何利用IO流接收頁面的輸入信息,及推送輸出信息至頁面的過程。
WebSocket協議是基于TCP的一種新的網絡協議,它實現了瀏覽器與服務器全雙工通信,允許Web服務器主動發送信息給瀏覽器客戶端。平臺的服務端Runtime類封裝了編譯命令的輸入和輸出流,而WebSocket則負責實現從瀏覽器中獲取輸入數據,提交給服務端Runtime封裝的編譯環境,再將編譯和運行的輸出流提交到瀏覽器的頁面上,實現編譯環境Web平臺的實時交互。
整個可視化教學平臺是一個描述流程圖模型、演示流程圖模型的工具,為了提高學習者的抽象思維能力,在“實際問題”和“程序代碼”之間增加一層更為直觀的“可視模型”,同時也提供了從“模型”生成“代碼”的模塊。輔助學生形成一套完整的“問題-模型-代碼”思維鏈條[7-9]。
根據模型設計和演示的原則,設計了如圖1所示的系統架構, 整個系統分為2層9個模塊,客戶端主要負責與用戶交互,實現模型繪制、動畫演示、代碼和運行結果顯示的功能。服務端負責模型的保存,解析,及源代碼的生成、編譯和運行控制功能。
客戶端是交互的核心區域,模型繪制和模型傳輸都依賴于JSON模型的描述,HTML5中提供了一套完整的2D圖形繪制組件,可將流程圖中的節點與JSON對象關聯起來。
當提交流程圖模型后,JSON模型以.flow文件的形式持久化的保存與后臺服務中,生成源代碼時,模型被提交至Web服務中的模型轉換模塊處理,解析模塊將JSON對象與程序中標準語句元素關聯起來,將這些解析后的語句元素填寫入基本程序框架(開始-輸入-處理-輸出-結束),生成源代碼。
Runtime類可接管系統程序的輸入和輸出,封裝后的編譯環境可以將源代碼的編譯結果以流的形式推送給控制臺組件顯示出來。如果編譯成功,則生成的可執行程序也用Runtime類封裝,將執行結果同樣以流的形式推送給控制臺。

圖1 可視化編程平臺系統架構Fig.1 The Architecture of Visual Programming Platform
整個平臺包含了流程圖繪制區、模擬執行區、源碼生成區和控制臺,如圖2所示。

(a)—界面設計圖; (b)繪圖界面效果圖2 可視化編程平臺界面Fig.2 The interface of visual programming platform
1) 流程圖繪制區: 繪制流程圖模型,包括了繪圖工具箱、畫布(提供網格)、配置窗口。
2) 模擬執行區:可以按步驟自動執行和按步手動執行。通過節點依次獲取焦點的方式表示當前執行的語句,并在輸入時彈出輸入框,控制臺上同步顯示相關輸出信息。
3) 源碼生成區: 可根據流程圖生成相關代碼,用戶可調整代碼,并編譯執行,代碼可將執行結果返回到控制臺上。
整個流程圖模型可以看做節點和連線,以及輔助的文本描述。節點區分為“開始|結束”“語句框”“判斷框”。連線代表了語句處理的方向。描述模型的關鍵點需要用JSON格式來描述節點和連接,并保存為.flow模型文件。
1) 節點的JSON描述。描述節點主要包括外觀屬性和業務屬性。其中外觀屬性有形狀,坐標,大小,業務屬性有類別、偽代碼、說明。因此節點的JSON表示可以如下:
node={id:“n0”,type:“input”,express:“score”,initValue: 0.0 prompt:“Please input score:”, src: “img/input.png”,x:100,y:100,w:100,h:100...}。
其中節點類別的type可以分為: input輸入、output輸出、set賦值、call調用、decision判定、empty空節點(用于連線匯聚);其輸入、賦值、調用時的變量類型,可根據具體輸入、賦值、調用時的常量或變量來決定變量名和數據類型;
2) 連線的JSON描述。連線描述了流程圖語句節點間的執行次序,一條連線必須連接2個節點,描述連線主要有線條標記,起點、終點等信息。因此連線的JSON表示可以如下:
link={id:“l0”,type:“t_indicator”,from:“n0”,to:“n1”...}。
JSON模型的作用是建立起流程圖和程序代碼間的映射關系,參照表1流程圖節點→JSON對象→代碼元素的映射關系表。

表1 流程圖節點-JSON對象-代碼元素映射關系Tab.1 Relation of flow-chart’s node and JSON object and code unit
流程圖繪制主要依賴Canvas的使用,Canvas本質上是一個容器,容納著各種圖元對象。繪圖模塊和JSON描述的節點和連線是聯動的,每添加一個節點和連線會生成相應的JSON模型代碼。要創建一套2D繪圖環境,主要包括2方面的基本功能:
1) 創建繪圖區域,在網頁中添加Canvas標簽元素,即可獲得一個以左上角為坐標原點,X軸向右延伸,Y軸向下延伸的繪圖區域。然后獲取繪圖的上下文環境(Context)。 其中定上下文環境中定義著所有繪圖2D圖形的屬性和命令,各種繪圖操作都依賴著它。
var context=document.getElementById(“canvas”).getContext(“2d”);
2) 節點和連線的繪制,在流程圖中節點可以利用圖片效果展示,比直接使用繪制矩形命令更加簡單和美觀,也方便實現節點的縮放、拖動和動畫效果展示。構造節點需要先定義圖片對象var input_img=new Image(); 再加載圖片文件input_img.src=“img/input.png”; 這樣就可以在指定坐標添加圖片對象context.drawImage(input_img,x,y,w,h);同時需要設定拖動屬性draggable=“true”和拖動事件ondragstart=“drag(event)”支持節點的拖動。連線則利用context.moveTo(x1,y1)和context.lineTo(x2,y2)實現兩點間的線條繪制,90度折線則采用劃線函數組合實現,最后以context.fill()/stroke()填充線條相關風格。
流程圖的動畫執行分為自動執行和交互處理,自動執行可以通過setInterval(call(),時長)的函數設置每個節點執行的間隔,call( )為自定義的js函數,實現了當前節點高亮顯示、代碼表達式解析、控制臺信息顯示、標記下一個執行節點的功能。當需要交互時(如:輸入操作),則clearInterval暫停,彈出輸入框。當調用包含算術表達式和邏輯表達式的節點時,則將字符串的表達式轉換為js的表達式進行計算和處理。
流程圖模型生成代碼的過程屬于軟件正向工程的范疇,需要解決模型結構元素和源代碼間的映射問題,即是由不同類型的節點和源代碼之間形成的映射關系表的管理,例如輸入和輸出節點可映射為scanf、printf語句,當用戶輸入帶小數點的數值時可映射出雙精度變量定義語句等。將解析出JSON文件中節點元素并按照映射表生成相關代碼[10-11]。給出了有向圖強連通分量的識別算法可區分出判斷框節點屬于循環結構或分支結構,如圖3所示。描述了包含(a)while和(b)do-while結構的流程圖,轉換為相應的有向圖, 并通過深度優先搜索識別圖中是否存在強連通分量,如果存在強連通結構則為循環結構,否則為判斷結構。此外,分析連線的匯聚Empty節點(B)和判斷框節點(C)的前后關系識別出循環的種類。如果有向圖存在(B,C)連線為while循環,如果存在(C,B)連線則為do-while循環。

(a)—while有向圖G中包含(B→C)分量; (b)—do-while有向圖G中包含(C→B)分量圖3 循環結構對應的有向圖強連通圖Fig.3 The strongly connected graph for cycle structure
在生成代碼后通過調用gcc命令編譯為可執行文件(.out),例如:“gcc sc.c-o sc.out”。整個編譯過程可通過后臺Java的Runtime類加載為JVM下運行的進程。編譯后的可執行文件也由Runtime類封裝調用,并通過捕獲輸入流、輸出流和錯誤流的方式返回執行情況。
整個過程分為3個步驟,如圖4所示。

圖4 集成C語言編譯和執行模塊的架構圖Fig.4 The Integrated Module for Compilation and Execution
首先通過Runtime調用可執行文件,并捕獲了輸入和輸出流發布至Web服務,通過HTTP方式與WebSocket通信,具體如下:
1) Runtime封裝執行命令Process p=Runtime.getRuntime().exec(“./sc.out”);調用該語句后,Process類即可封裝sc.out的執行過程,并提供操作系統管理進程的基本操作,例如:waitFor(等待)、destory(殺死)等方法。同時通過輸入和輸出流的方式與Process交互,實現進程運行時的輸入、輸出和報錯管理。
2) 捕獲執行的信息流,InputStream err=p.getErrorStream()該方法可捕獲執行程序時的報錯信息流。InputStream in =p.getInputStream()該方法將獲得輸入信息流,封裝為BufferReader對象br,從流中可讀取執行程序的輸出信息。當String msg=br.readLine()進入阻塞狀態時,可判定為等待輸入。利用OutputStream out=p.getOutStream()該方法將獲得輸出信息流,封裝為BufferWriter對象bw,通過bw.write(data)和bw.flush()將輸入值提交給執行進程,并喚醒阻塞的輸出進程。
3) 與前臺控制臺交互,需要在Web服務端定義SocketSrv(繼承自WebSocketServlet),負責與頁面中的WebSocket對象實現雙向通信[12]。ws=new WebSocket(“ws:∥localhost:8082/socketService”); 一方面能將后臺br.readLine()讀取到的消息推送至頁面ws.onmessage=function(event){console.log(event.data);},另一方面可將前臺頁面的輸入數據(data)通過s.send(data); 提交給后臺的bw.write(data),實現執行程序的輸入。
研究利用HTML5的2D繪圖技術構建一套可視化的編程語言教學環境,給出流程圖模型到源代碼轉換的基本思路,以及集成編譯環境的方法。該軟件集成了流程圖繪制、演示和源代碼的生成等功能,且具有靈活的交互界面和發布方式,已經在程序設計語言教學中得到了應用,取得了良好的教學效果。
目前,該平臺主要生成C語言的源代碼,其他語言則需要重新定義一套新的代碼生成模塊和集成語言編譯環境模塊。同時,對于C語言中部分特定的數據類型(如:指針、結構體、共同體等)、運算符(位運算,逗號表達式等)和語法結構(如:break,continue,goto等)的支持不足,隨著軟件不斷完善,這些問題會得到很好的解決。
參考文獻:
[1]程向前. 基于流程圖的可視化程序設計環境對大學計算機基礎教學的影響[J]. 計算機教育, 2012(14):56-59.
[2]蔡慧英,陳婧雅,顧小清. 支持可視化學習過程的學習技術研究[J]. 中國電化教育, 2013(12):27-33.
[3]HU Chunghua,WANG Fengjian. Constructing an integrated visual programming environment[J]. Software-Practice and Experience, 2015,28(7):773-798.
[4]CARLISLE MARTINC. RAPTOR: RAPTOR: A Visual Programming Environment for Teaching Algorithmic Problem Solving[EB/OL]. [2017-05-08]. https:∥www.researchgate.net/publish /221537443_RAPTOR_A_visual_programming_environment_for_teaching_algorithmic_problem_solving.
[5]戴松,許冉,周忠. 基于HTML5的算法動畫可視化平臺[J]. 系統仿真學報, 2013(25):2436-2441.
[6]傅金枝,黃世梅. 基于HTML5的數據結構算法演示系統的設計與實現[J]. 實驗室科學, 2015(2):72-75.
[7]PRAKASH H O,BHOSHAN R P. Venkataraman integrated visual programming environment[J]. International Journal of Modeling & Optimization, 2013:256-260.
[8]劉孟仁,劉海慶. 軟件可視化技術及其應用研究[J]. 計算機應用研究, 2002,19(6):26-28.
[9]周忠,強津培,戴松. 算法可視化的計算機輔助教學平臺設計與實踐[J]. 計算機教育, 2014(16):81-84.
[10]王黎明,王幗釹,周明媛,等. 程序流程圖到代碼的自動生成算法[J]. 西安電子科技大學學報(自然科學版), 2012(6):70-77.
[11]HAMID B,KEVIN S. Monarch: Model-based Development of software Architectures[C]∥Proc of the 13th International Conference on Model Driven Engineering Languages and Systems : Part Ⅱ (MODELS 10). Antwerp:Springer, 2010:376-390.
[12]李錫輝,楊麗. 基于WebSocket的服務器推送技術研究[J]. 網絡安全技術與應用, 2014(6):45-46.
[13]趙慧臣. 知識可視化視覺表征的形式分析[J]. 現代教育技術, 2012,22(2):25-30.
[14]劉海,李姣姣,張維,等. 面向在線教學平臺的數據可視化方法及應用[J]. 中國遠程教育, 2018(1):37-44.
[15]李芒,蔡旻君,蔣科蔚. 可視化教學設計方法與應用[J]. 電化教育研究, 2013(3):6-22.