何 希,陳 佳,農 健
(梧州學院 大數據與軟件工程學院,廣西 梧州 543002)
“編譯原理”課程是一門介紹編譯器工作原理和方法的課程。它是高等學校培養計算機專業人才的主干課程之一,也是一門對理論、實踐要求都很高的課程。它既要求學生理解編譯原理、編譯系統結構、各種編譯算法,又需要學生具備設計、完成、分析和維護編譯程序的初步能力。同時,“編譯原理”課程又是計算機專業中一門綜合性很強的專業課程,需要以多門前修課程為基礎,如“數據結構”“離散數學”“操作系統”“程序設計”“匯編語言”等等。
據筆者了解,目前大多數“編譯原理”課程的內容包括詞法分析(正則表達式、非確定有限自動機、確定有限自動機)、語法分析(上下文無關文法、自上而下語法分析、自下而上語法分析)、語義分析和中間代碼生成(屬性文法、語法制導翻譯形成中間代碼)、代碼優化(局部優化、循環優化)和目標代碼生成。同時,一些“編譯原理”課程還會針對某些課程內容進行一些小型項目實踐和練習。
由于編譯系統復雜,所涉及的理論寬廣且深奧,而且課程涉及多門前修課程,大多數學生反映此課程內容枯燥、抽象、復雜。同時,由于課程講授難度大,學生積極性不高,參與度低,很多教師也不愿意開設“編譯原理”課程。有的高校為此縮減了“編譯原理”課程的課時個別高校甚至把此課程從人才培養計劃中刪除。筆者分析有以下原因造成了“編譯原理”課程目前的困境:(1)課程內容的設置偏理論輕實踐。編譯系統中有大量的理論內容,這些內容對于本科學生來說比較抽象甚至是晦澀難懂,而且在實際中應用不多。很多教師不得不把大部分時間用來解釋這些理論內容,從而留給學生實踐的時間不多,進而增加了學生理解理論知識的難度。(2)學生基礎參差不齊。部分學生在修該課程前并沒有打好基礎,造成了理解上的障礙。(3)教師自身功底薄弱。(4)實踐環節的開創性和實用性不夠。由于時間的關系,學生很難實現一個完整的編譯器。即使是簡化版的計算機語言,其編譯器的開發難度也是遠遠超出“編譯原理”課程項目的范疇。然而,如果學生沒有一個從無到有設計和完成一個編譯器的經歷,那么他們對編譯原理的理解、對編譯中涉及算法的理解都會大打折扣。
針對“編譯原理”課程存在的問題,許多研究提出了不同的解決方案。文獻[1]提出課內因材施教、理論聯系實際。讓學生上講臺授課。課外組織答疑,采用加分規則提拔優秀學生。文獻[2]提出有效教學,豐富教學手段,加強實踐教學。文獻[3]提出引用4個實驗項目來幫助學生掌握理論知識。文獻[4]提出理論與實踐并重,并且選擇C語言的編譯程序作為實驗內容。同時,選擇得當教學方法。文獻[5]提出理論課教學應該體系完整、結構清晰、內容貫通,同時倡導采用CAI軟件進行教學。文獻[6]建議課程教師對教材及教學內容做一定程度的處理,對層次較低的學生則可適當降低難度,對層次較高的學生可加入與編譯有關的最新內容,激發學生對編譯的興趣。
筆者的基本思路是通過一個小型的、完整的編譯器項目來引導整個“編譯原理”課程。課程的考察方式摒棄了傳統的期末閉卷考試,避免學生死記硬背編譯理論和算法。課程根據每個學生團隊所承擔編譯器項目的完成度來進行評估,讓每個學生都有參與感,發揮主觀能動性來學習編譯器相關知識。一個具體的編譯器項目可以讓學生理解編譯問題是在什么背景下產生的,編譯理論是基于哪些假設而產生的,而編譯算法又是如何解決這些問題的,有哪些優點,有哪些妥協。項目中的代碼更是可以讓學生更好地理解編譯器結構以及各種編譯算法的實現。課程的編譯器項目可以細分為詞法分析模塊、語法分析模塊、語義分析模塊、執行模塊。各個模塊分階段提交、評估。編譯理論、編譯相關算法的講授以服務編譯器項目為出發點,對現有內容進行斟酌、調整。 對于絕大多數學生而言,將來都不一定進行編譯器方向深入的研究。對于他們而言,理解編譯器的基本原理、工程上設計和實現顯然更加重要和實用。
在筆者的教改方案中,選擇合適的“編譯原理”課程項目是決定整個課程成敗的關鍵。首先,這個課程項目一定要相對完整,包含編譯系統的主要模塊。這樣學生才可以對整個編譯系統有完整的理解。其次,這個課程項目的工作量是在學生能力范圍之內的,可以由學生團隊在一個學期內完成。一般常見計算機語言的編譯器,如Java編譯器, C編譯器, 其代碼量都是驚人的,哪怕是精簡版的編程語言,如miniJava, 其編譯器的實現也會因為工作量太大而不適合作為本科生“編譯原理”課程項目。筆者在讀研期間,曾經為Datalog語言[7]編寫過編譯器。Datalog語言是一種接近SQL的數據庫查詢語言,其精簡語法如下:
(1)ddb ∷= idb_rules DOLLAR
(2)idb_rules ∷= idb_rule|idb_rule idb_rules
(3)idb_rule ∷= NAME LPAREN arg_list RPAREN IMPLIES idb_body PERIOD
(4)idb_body ∷= literal|literal COMMA idb_body
(5)literal ∷= NOTOP predicate|predicate
(6)predicate ∷= NAME LPAREN arg_list RPAREN|arg COMPARISON arg
(7)arg_list ∷= arg|arg COMMA arg_list
(8)arg ∷= NUMBER|STRING|VARIABLE
從上面Datalog語言的語法可以看到,Datalog語言中單詞種類少,其編譯器中的詞法分析模塊相對簡單,只有8條語法規則,決定了其編譯器中的語法分析模塊不會太復雜。因此,Datalog語言編譯器項目是一個工作量適中,非常適合作為“編譯原理”課程的項目。實際上,在實驗環節中,該課程教師向學生介紹2款工具JFlex[8]和CUP[9],學生可以通過這2款工具配置、定制產生詞法分析模塊和語法分析模塊,大大減少了編碼工作量,而且可以更加專注地理解編譯器的工作原理。同時,還為編譯器中每個模塊以及一些重要的功能點提供了測試案例,幫助學生在分模塊開發過程中進行單元測試,減輕學生的工作量。
Datalog語言編譯器中的語義分析模塊需要一些Datalog語言的使用經驗,鑒于大多數學生在數據庫原理課程中都學習過與Datalog語言類似的SQL語言,在筆者適當的提示和幫助下,學生可以在短期內熟悉理解Datalog語言。最后,課程教師會提供基礎的基于Datalog語言的數據庫及管理程序,以便于學生在完成整個Datalog語言編譯器后可以使用Datalog語言執行數據庫查詢以測試編譯器的正確性。
筆者在具體的課程實踐中發現,通過組建團隊的形式,大多數學生是可以在一個學期的“編譯原理”課程中完成此編譯器項目的。
在筆者的教改方案中,“編譯原理”課程的講授思路已經從原來的重理論輕實踐轉變為以項目為核心,理論與實踐并重。課程的考核方式也由期末閉卷考試轉變為基于編譯器項目的分階段考核。針對實踐性強的內容,如DFA化簡,自上而下語法分析,還會采用課堂小測驗的方式進行考查。
筆者對課程內容進行了優化。基本思路就是從傳統的面面俱到、相關理論和算法都涉及,到現在的以應用為導向,重點突破。(1)將與編譯器項目相關的編譯理論和算法作為重點講授對象。以語法分析為例,相關的算法很多,如果在課程中全部覆蓋,哪怕是部分覆蓋,都會占用很多時間,而且學生如果沒有在實際中應用到這些算法,他們也很難理解和記住。所以課程教師會挑選在項目中實際應用到的自上而下語法分析算法重點講述。(2)將理論證明作為可選內容,讓學有余力的學生按需學習,課程教師提供必要的幫助。對學習課程吃力的學生不做要求。(3)將一部分高級的內容從課程內容中移出,放在針對研究生的“編譯原理”課程中。例如,寄存器分配,涉及一些高階知識,并不適合給本科生講授。(4)適當補充一些涉及到的知識點。例如,形式語言,與課程相關度高,需要在課程中安排時間給學生補充或復習。
該課程對教材的選用也非常重視。很多“編譯原理”課程采用的Alfred V. Aho編著的《編譯原理技術和工具》。此書被認為是編譯領域的經典教材,將編譯原理寫得非常深入。然而,筆者認為此書并不一定適合作為普通計算機本科學生的“編譯原理”課程,因為本科階段的“編譯原理”課程沒有必要涉及很深奧的理論。相比之下,Andrew W. Appel編著的《現代編譯原理-C語言描述》更適合課程的需要。同時,在互聯網時代,筆者希望可以充分利用網絡中的各種電子資料和視頻資料,特別是名校的公開課視頻,其往往比傳統的紙質教材更容易讓學生接受。
為了進一步提高教育質量,筆者在“編譯原理”課程的教學中采用了一些新的方法:
(1)建設“編譯原理”課程網站。網站集合了課程相關的幻燈片、習題、參考資料、課程項目。讓學生隨時可以獲取課程相關信息。
(2)課后設置專門的答疑時間。
(3)反轉課堂。鼓勵學生上講臺講解編譯知識,課程教師點評。
(4)鼓勵學有余力的學生參與編譯方面的研究項目。
(5)采用CAI教學,加深學生對編譯原理概念的理解。
(6)以學生團隊為單位,研究相關的論文并報告。
筆者在本科生的“編譯原理”課程中嘗試了本文討論的教學改革方案,其教學安排見表1。

表1 編譯原理課程教學安排
得到以下總結和反饋:
(1)學生上課積極性普遍提高,踴躍參與課堂討論。
(2)學生對課程項目非常感興趣,自發討論不同的解決方案。
(3)課程項目對學生的編程要求較高,有一部分編程基礎差的學生對于課程項目實施比較吃力,因而也影響了他們理解課程。
(4)每隔2周1次的課堂小測驗對于督促學生學習非常有好處。
(5)由于既要備課、上課,也要負責在課后給學生答疑以及批改作業,課程教師的工作壓力較大,建議給“編譯原理”這門課配備2個學生助教。
“編譯原理”課程是計算機專業的核心課程,是所有計算機學生都應該認真掌握的課程。針對目前此課程所面臨的困境,我們提出了以一個小型編譯器項目為核心、理論與實踐并重的“編譯原理”課程改革方案。將編譯原理和工程實踐相結合,旨在提高學生的積極性和參與度,提高整個“編譯原理”課程的教學質量。
目前,梧州學院大數據與軟件學院有一個招收外國留學生的計算機科學與技術專業,筆者正在籌劃將教學改革后的“編譯原理”課程加入其專業選修課中,將教改成果向他們推廣。