張 莉 楊海燕 史曉華



摘要:“編譯技術”是一門公認的難教難學的課程,包含了看似晦澀的理論部分和覆蓋面廣的實踐部分。如何根據本學校的培養定位組織教學內容,如何實施教學過程,是教師們普遍關注的主要問題。本文結合北京航空航天大學這類工科院校強調工程技術的特點,探討了“編譯技術”課程的組織方式,提出了以編譯過程為主導帶動課程知識點的課程安排模式,并針對不同類型高校給出了教學安排建議。
關鍵詞:編譯技術;編譯原理;課程定位;課程內容組織
中圖分類號:G642 文獻標識碼:B
1引言
“編譯原理/技術”是計算機專業的一門經典課程。由于該課程包含了詞法分析、語法分析方法中與形式語言及自動機相關的讓人頗感晦澀的原理,以及在代碼生成和代碼優化部分與計算機系統結構有關的龐雜繁瑣的實現技術,讓許多非計算機相關專業的學生望而卻步,幾乎成為計算機專業“科班出身”的一種標志。與此同時,難教難學也是這門課的一個特點。如何讓那些看似晦澀的原理和龐雜的實現技術對學生來說更容易理解和掌握呢?筆者認為,教學內容的組織和課程安排模式是非常重要的因素。同樣的知識點,因不同的組織方式而變得邏輯性更強,更容易理解和掌握。本文結合北京航空航天大學編譯課程的建設,探討以編譯過程為主導帶動課程知識點的課程組織模式。
2課程定位
編譯課程在不同學校教學計劃中的教學定位可能不同。北京航空航天大學(簡稱北航)是一所具有航空航天特色和工程技術優勢的多科性、開放式、研究型大學。北航計算機學院將編譯課程設置為一門核心專業必修課,并命名為“編譯技術”(而非“編譯原理”),意在秉承工程院校強調工程技術的特點,強調編譯系統的構造及其相關技術。本課程安排在大三上學期,先修課要求:一門高級程序設計語言、“數據結構和算法”以及“計算機原理和匯編語言”等課程。同時本課程安排在“操作系統”之前,是學生接觸到的第一個講述完整的軟件系統的課程。本課程理論和實踐并重,要求學生掌握編譯的基本理論、常用的編譯技術,了解編譯過程及編譯系統的構造(結構和機理);能運用所學技術解決實際問題,能獨立編寫一個小型編譯系統。
曾經一度,有人認為學生畢業后很少做編譯器了,因此不必再開設編譯課了。Alfred V. Aho在其著名的《編譯原理》(龍書)中提到:編譯器設計的原理和技術還可以用于編譯器設計之外的眾多領域,這些原理和技術通常會在一個計算機科學家的職業生涯中多次被用到。因此,編譯課程在本科教學體系中應該承載超越“編譯系統構造”的使命。筆者認為,“編譯技術”課程作為一個載體,在培養學生專業素質方面起到了非常重要的作用,主要體現在:(1)讓學生理解高級程序設計語言的工作原理和相關概念;(2)通過編譯程序的構造和相關算法,讓學生掌握軟件領域重要的程序(模型)等價轉換技術、程序(模型)優化技術;(3)通過編譯系統的介紹,讓學生了解軟件系統的概念和軟件系統設計的方法;(4)通過學習詞法分析程序、語法分析程序的自動生成技術,讓學生對程序的自動生成技術有所了解。
基于這樣的理解,北航編譯課程的培養定位為:基礎和前沿相結合、理論和實踐相結合。要求學生既要掌握編譯的經典基礎理論和算法,對編譯系統有完整的理解,又要求學生具備簡單編譯系統的構造能力。
同時通過“編譯課程設計”實踐課程,讓學生:(1)掌握編譯程序構造的主要技術和算法,理解編譯過程;(2)體驗一個比較完整的軟件系統的設計、開發、測試過程,建立系統設計觀念;(3)結合軟件工程課程,完成規范化文檔;(4)在本科培養體系中,進一步提高數據結構的綜合應用能力和程序設計能力。
3課程的組織
基于以上的定位,筆者認為“編譯技術”課程的組織應強調過程完整性、系統性和實踐性。
(1) 過程完整性:編譯過程是一個翻譯的過程,編譯技術的實質是介紹程序/模型從一種語言表達形式到另一種語言表達形式的等價轉化方法,所以在課程內容的安排中應該保證編譯過程的完整性,至少是一個完整的翻譯過程。
(2) 系統性:編譯器是一個完整的軟件系統,也是學生接觸到的第一個系統(之前學生接觸到的主要是針對語言、數據結構和算法的程序設計練習)。應該讓學生理解一個完整的系統是如何構成的,各部分應如何組織和協調。
(3) 實踐性:理論應該和實踐相結合,無論是研究性大學、非研究性大學,都應該注重實踐和學生動手能力的培養,尤其是對計算機專業的學生,實際動手能力關乎謀生大計,更不能小視。北航計算機學院為了突出實踐環節的重要性,將實踐環節部分設置為一門課程,單獨計算學分。我校該課程的組織如下:
(1) 教學內容組織(理論課部分)
編譯課程中晦澀的原理和龐雜的算法總有些讓人望而生畏,它們都是必需的嗎?它們之間是什么關系?學生理解嗎?教師清楚嗎?因此,讓復雜的內容簡化,讓課程更簡單易懂,成為本課程改革的一個重要指導思想。在十多年的教學過程中,筆者發現編譯過程是一根主線,所有的知識點都是為其服務的,為此提出了以編譯過程帶動課程知識點的課程組織方式。
通常,編譯過程可劃分為5個基本階段:詞法分析、語法分析、語義分析及生成中間代碼、代碼優化、生成目標程序,如圖1所示。經過詞法分析、語法分析、語義分析及代碼生成這3個階段,就能完成將程序從一種形式轉化為另一種形式,這就體現了一個完整的翻譯過程。因此,最基本的要求是保證這3個階段的內容完整。
要保證這3個階段的內容完整,并不意味著要介紹這3個階段的所有內容。其實,僅僅完成一個翻譯過程所涉及的內容并不多、也不難。詞法分析部分只需要讓學生理解詞法分析的功能,能基于狀態圖(狀態圖以一種直觀的形式描述單詞符號的拼寫規則)構造出相應的詞法分析程序。而在語法分析部分,可以只介紹最簡單的且便于手工編程實現的遞歸子程序法。在確定了每種語法成分后,結合該語法成分的語義,可以及時完成語言的翻譯,這就是語法制導翻譯方法。每種語法成分加上其語義的屬性,便構成了屬性翻譯文法。按照語法制導翻譯方法,對各種語法成分進行語義分析并生成另一種形式的代碼,這就完成了程序從一種語言形式到另一種語言形式的翻譯過程。這個過程主要涉及到詞法分析、語法分析和語法制導翻譯技術、語義分析和代碼生成、源程序的中間形式等內容。當然,作為基礎,學生應該首先了解文法和語言的概念和表示等基礎知識,如圖1中A框所示。
要真正實現上述語言的編譯過程,還需要了解符號表管理技術、錯誤處理技術,考慮到程序運行時需要解決的問題,還需要了解運行時的存儲組織及管理方式。這部分內容構成了基本翻譯過程之上第二個層次的知識點,如圖1中B框所示。
要生成高質量的目標代碼,還應該了解代碼優化和目標代碼生成有關的技術和方法。這可歸于第三個層次,如圖1中C框所示。
學生掌握了上述知識點,便為實現一個帶有代碼生成和優化的編譯器打下了基礎,可以不用了解在教學過程中被認為難講難學的詞法分析和語法分析的其他理論部分。這些讓人覺得晦澀的部分,究竟有什么作用呢?它們與編譯過程的前述知識點有什么關系呢?經過多年的教學,筆者發現,學生覺得這部分知識難學,并不是真正學不懂,他們更多的是不理解為什么要學,不能很好地建立這之間的邏輯關系。首先,我們來看看占據詞法分析2/3的內容,是介紹詞法分析器的自動生成技術,而自動機理論是其自動生成的理論基礎。再看看語法分析部分,是學生認為最難學的部分,往往也是各個學校考查學生的重點內容。可是,大部分學生并不完全明白為什么要學習這些內容,沒有認識到(或者教師沒有講解)每種方法的局限性,沒有理解各種方法從簡到難,同時其處理語言的范圍也從小到大(見圖2),沒有理解這里還有相當的篇幅在介紹語法分析器的自動生成技術。正是由于介紹了語法分析器的自動生成技術,導致這部分內容涉及了相當多的理論原理和算法。對此,筆者建議不同學校可以根據教學要求適當選擇這部分內容開展教學(見圖1(C))。
上述知識點的組織方式可以用圖1來表示。圍繞編譯過程,將編譯技術的知識點分為三個層次,黃色A框表示實現一個語言翻譯過程所需的最基本的知識點,建議各個學校都講。進一步如果需要翻譯生成的程序能在虛擬機上運行,翻譯過程能夠進行簡單的語義檢查和錯誤處理,還需要增加符號表管理、錯誤處理和運行時存儲組織管理等方面的知識,這些內容不屬于編譯過程的某個具體階段,如綠色B框所示。其他有關詞法分析和語法分析自動生成的原理、代碼優化和代碼生成的知識點,可以作為第三個層次的內容,如紫色C框所示。不同的高校可以根據培養定位選擇相應內容講授。重要的是,所有內容應該圍繞一個完整的編譯過程,至少是一個完整的翻譯過程來進行,而不應該僅限于詞法分析和語法分析方法的介紹。
(2) 實踐環節要求
筆者認為,在“編譯技術”的實踐環節,應讓學生自己動手實現一個完整的編譯程序,從源代碼翻譯為目標代碼,并且要讓目標代碼能夠運行(至少能運行在虛擬機上)。這樣不僅讓學生體會完整的編譯過程,同時也讓學生實現一個完整的編譯系統。為此,北航計算機學院的“編譯技術”實踐環節設計了三個層次的題目,分別對應了不同的難度和分數,力求讓不同程度的學生都實現一個完整的編譯器,各難度的題目要求如表1所示。
從表1中可以看出,難度等級低的題目在文法要求上不高,與教材[3]中的PL/0文法類似,學生只要讀懂了教材中經典的示例編譯器,就應該能夠實現。由于有示例編譯器為參考,降低了難度,但同時也為考查學生是否獨立完成增加了難度。為此,筆者設計了一套質量管理體系,從題目設置、題目分配和考核方案等方面綜合考慮,加強過程管理,保證作業質量。比如,每個難度的文法都有若干個,每個文法定義的語言在形式上都有差別,學生必須按照自己所獲得的文法編寫編譯器,才能通過測試程序的測試;借助于教學平臺,每個難度的若干個文法隨機分配給學生等,參見精品課程網站http://compile.buaa.edu.cn。
4總結
為了讓“編譯技術”課的內容更好地被學生掌握,為了更好地實現編譯課程的教學使命,本文提出了以編譯過程為主導帶動課程知識點的課程組織模式,從另一個角度理清了那些看似晦澀的理論部分和編譯過程的關系,而以編譯過程為主導劃分的三個層次知識點,也有利于各種不同定位的高校安排教學內容。筆者認為,無論哪類學校,只要是工科院校,都應該強調實踐,都應該保證編譯過程的完整性,讓學生用最簡單的方式至少完成一個完整的翻譯過程。在此基礎上,根據各個學校的定位適當增加詞法分析和語法分析的自動生成技術,以及編譯優化技術。
筆者在教學實踐中發現,學生在自己編程實現了一個小型編譯程序之后,通常會感慨理論課上覺得已經學會的東西,在實踐之后才發現真正理解和掌握了。北航計算機學院的“編譯技術”實踐部分,由于有寄存器分配、生成匯編碼等要求,需要學生運用C語言、數據結構、計算機原理和匯編等知識,被學生譽為“綜合性的大作業”。盡管難度大,但是學生覺得收獲頗豐,這正是筆者不斷思考、嘗試新的教學方法的無窮動力。
參考文獻:
[1]Alfred V. Aho, Monica S. Lam,Ravi Sethi,et al. 編譯原理[M]. 趙建華,鄭滔,戴新宇,譯. 北京:機械工業出版社,2009.
[2]Andrew W. Appel, Maia Ginsburg. Modern Compiler Implementation in C[M]. Cambridge: Cambridge University Press, 1998.
[3] 高仲儀,金茂忠. 編譯原理及編譯程序構造[M]. 北京:北京航空航天大學出版社,2001.
[4] 楊海燕,史曉華,張莉.“編譯技術”實踐環節的質量管理體系及實踐[J]. 計算機教育,2009(17):61-63.