摘要:結(jié)合編譯課程教學(xué)特點,收集當(dāng)前常用的編譯資源,并從編程語言和教學(xué)知識點兩個角度對這些資源進(jìn)行歸類分析;在此基礎(chǔ)上,探討如何利用這些資源開展編譯課程的課堂教學(xué)和實踐教學(xué)。
關(guān)鍵詞:編譯原理;工具資源;實踐教學(xué)
1.背景
編譯理論與技術(shù)是計算機科學(xué)中發(fā)展最迅速、最成熟的一個重要分支,程序設(shè)計語言和編譯的發(fā)展集中體現(xiàn)了計算機科學(xué)的重要成果與精華。編譯原理課程是計算機科學(xué)與技術(shù)專業(yè)的專業(yè)必修課程,主要講授程序設(shè)計語言編譯程序構(gòu)造的基本原理和方法。編譯程序的開發(fā)堪稱經(jīng)典理論和先進(jìn)技術(shù)緊密結(jié)合的典型示范,因此理論學(xué)習(xí)和實踐的緊密結(jié)合是本課程的突出特色。通過編譯程序構(gòu)造的問題,可以體驗到如何從實際需求中提出理論問題、理論研究推動技術(shù)進(jìn)步、運用技術(shù)工具解決實際問題的過程。
在經(jīng)典理論的支持下,在編譯程序的研制過程中,產(chǎn)生了非常豐富的工具資源。在這些工具資源的支持下,編譯程序開發(fā)的自動化程度得到了顯著提高;相對其他軟件開發(fā)任務(wù),編譯程序開發(fā)在效率和質(zhì)量上的優(yōu)勢非常明顯。更為重要的是,編譯的理論和技術(shù)對于計算機科學(xué)中的其他領(lǐng)域也有重要的影響。一直以來,編譯的理論和技術(shù)在程序設(shè)計語言的實現(xiàn)、針對計算機體系結(jié)構(gòu)的優(yōu)化、新的計算機體系結(jié)構(gòu)的設(shè)計、自然語言理解、網(wǎng)絡(luò)信息處理、網(wǎng)絡(luò)協(xié)議的分析與實現(xiàn)等領(lǐng)域都是不可或缺的。國外著名大學(xué)(如美國哥倫比亞大學(xué)、哈佛大學(xué)和斯坦福大學(xué)等)的編譯課程教學(xué)都特別重視相關(guān)的課程實踐項目。以哥倫比亞大學(xué)為例,在編譯原理的課程教學(xué)中開展了貫穿整個學(xué)期的課程實踐項目。在項目中,學(xué)生分成小組,自主設(shè)計并實現(xiàn)一個小的語言,而這個語言涉及了豐富的領(lǐng)域,包括量子計算、音樂合成、計算機圖形學(xué)、游戲、矩陣計算和很多其他領(lǐng)域。在這些教學(xué)實踐中,很多編譯開發(fā)工具都被應(yīng)用于各種案例中,包括ANTLR、LEX和YACC等編譯領(lǐng)域經(jīng)典的開源軟件工具。
通過收集編譯資源(包括開源的編譯器和編譯程序開發(fā)工具),以及這些工具在計算機科學(xué)各領(lǐng)域中的成功應(yīng)用案例,可以為開展案例式教學(xué)改革打下堅實的基礎(chǔ)。筆者收集了編譯領(lǐng)域常用的開源軟件工具及其應(yīng)用案例,并對其進(jìn)行歸類分析和整理,以形成支撐編譯課堂教學(xué)和實踐教學(xué)的資源庫。基于該資源庫,在今后的編譯原理課程教學(xué)中,可以通過采取基于案例的教學(xué)方法,形象地向?qū)W生展示編譯研究中“經(jīng)典理論和先進(jìn)技術(shù)有機結(jié)合”的突出特點,使學(xué)生能夠通過具體的案例切實體驗編譯經(jīng)典理論在各領(lǐng)域的重要作用。
2.編譯資源分析
在幾十年的研究過程中,編譯領(lǐng)域已經(jīng)形成了很多編譯資源,如LEX、YACC、JavaCC為代表的編譯模塊開發(fā)工具,以及精簡語言編譯器、產(chǎn)品級開源編譯器等。這些工具實現(xiàn)了從Ada、C、Pascal等面向過程語言到Java、C++等面向?qū)ο笳Z言的編譯程序,覆蓋了文法、詞法分析、語法分析、中間代碼生成、代碼優(yōu)化、目標(biāo)代碼生成等編譯原理教學(xué)中所有的知識點?;谶@些工具也開發(fā)了SQL、XML分析等計算機科學(xué)其他領(lǐng)域的應(yīng)用。下面,筆者從生成語言、知識點覆蓋等角度對互聯(lián)網(wǎng)上的編譯資源進(jìn)行整理分析。
2.1從編程語言的角度分析
從編譯資源所面向的程序語言來看,從面向特殊領(lǐng)域的Fortran語言、DSP語言,面向過程的C語言、Pascal語言,到常見的面向?qū)ο蟮腏ava語言、C++、C#語言等,均有種類繁多的分析器、生成器、目標(biāo)代碼優(yōu)化器等可用于案例教學(xué)的編譯資源。
1)面向過程語言的編譯資源。
這方面的編譯資源主要針對C語言和Pascal語言。C語言作為最被廣泛使用的編程語言,也擁有最多的編譯工具資源,如YACC、LEX、ACCENT、BANSHEE等經(jīng)典工具均可用來產(chǎn)生C語言編程的分析器、生成器。其中,最知名的C語言解析器生成器YACC已經(jīng)在各種場合得到了廣泛應(yīng)用。YACC也是常用于編譯課程教學(xué)的工具,它采用LALR(1)語法分析方法,最初由AT&T為Unix操作系統(tǒng)開發(fā),在漫長的演變中產(chǎn)生了如Berkeley YACC、GNU BISON、MKS YACC和Abraxas YACC等變種版本,也出現(xiàn)了AYACC、YACC++等面向ADA、c++其他語言的編譯器。由于所產(chǎn)生的解析器需要詞法分析器配合,因此YACC經(jīng)常和詞法分析器產(chǎn)生器LEX一起使用,目前已有IEEE相關(guān)標(biāo)準(zhǔn)對YACC和LEX的功能進(jìn)行了標(biāo)準(zhǔn)化描述。此外,ACCENT、BEG、CKIT等面向c語言的編譯資源也可以用于編譯課程教學(xué)。據(jù)我們初步統(tǒng)計,目前互聯(lián)網(wǎng)上可用的針對c語言的編譯資源多達(dá)20余種,涵蓋了詞法分析、語法分析、前端、后端生成器、代碼優(yōu)化、程序分析等編譯過程中的各個環(huán)節(jié)。
2)面向?qū)ο笳Z言的編譯資源。
面向?qū)ο笳Z言已成為程序開發(fā)的主流語言,在應(yīng)用層軟件、網(wǎng)絡(luò)服務(wù)開發(fā)上占據(jù)著絕對優(yōu)勢地位。因此,目前也相應(yīng)出現(xiàn)了很多針對面向?qū)ο缶幊陶Z言的編譯資源,特別是C++語言和Java語言。C++語言由于與C語言一脈相承,許多針對c語言的編譯工具也擴(kuò)展了c++版本,如YACC++、Berkeley YACC、IDC-C等,均可以生成C/C++語言的分析器。
Java語言在最近20年一直是最流行的編程語言。Java語言為了實現(xiàn)跨平臺的目標(biāo),在編譯時僅生成字節(jié)碼,再由不同平臺的JVM生成目標(biāo)代碼執(zhí)行;因此,Java語言的編譯執(zhí)行具有明確的前端后端,非常有利于編譯程序的開發(fā)和編譯原理知識點的分解。目前針對Java語言的編譯資源與工具種類繁多,如JavaCC、JastAdd、Jax、Jfront、Soot、PAT等,我們目前已經(jīng)收集到相關(guān)編譯資源20余種,既有JavaCC等綜合編譯環(huán)境,又有Jfront前端工具、PAT正則表達(dá)式分析器、OOPS分析優(yōu)化工具等編譯工具資源。
3)其他專用語言、平臺的編譯資源。
為了符合特殊應(yīng)用場景的計算需求,出現(xiàn)了一些針對特定領(lǐng)域、特定平臺的程序語言,同樣,在這些領(lǐng)域中對編譯器往往也存在獨特的需求,如嵌入式系統(tǒng)、科學(xué)計算等,如針對SPARC平臺的編譯器BEG就能對Fortran、Modula等專用語言進(jìn)行分析編譯,而Archelon編譯器則針對DSP芯片為執(zhí)行代碼生成做了專門的優(yōu)化。ELI是這一類編譯資源的典型代表,它除了支持上述流行編程語言及專用語言如c、Fortran外,甚至支持對用戶定義的語言生成獨有的編譯器,從而幫助用戶快速地實現(xiàn)一種專業(yè)程序語言。
2.2從知識點的角度分析
為利于編譯原理課程的教學(xué),我們更希望從知識點的角度梳理相關(guān)資源,在講授相關(guān)課程時,可以介紹這些經(jīng)典的編譯工具。通過認(rèn)識真實編譯系統(tǒng)的工作流程和開發(fā)技術(shù),幫助學(xué)生理解關(guān)鍵知識點。我們從詞法分析、語法分析、編譯前端、編譯后端、程序分析及優(yōu)化、完整的編譯器平臺等類別對現(xiàn)有的編譯資源進(jìn)行了梳理和分類。
1)詞法分析。
詞法分析器以UNIX/LINUX上的LEX為典型代表,能夠生成c語言描述的詞法分析器;而AFLEX作為LEX的變種,能生成ADA語言描述的詞法分析器;Quex還能生成C/C++、Python語言描述的詞法分析器;相關(guān)的資源還包括LOLO、FLEX等。
2)語法分析。
支持語法分析的編譯工具最為豐富,從簡單到復(fù)雜的相關(guān)開發(fā)案例也最多,可以很好地用于支撐課程教學(xué)。如前文所述,語法分析器以YACC為典型代表,這一系列的語法分析器還包括AYACC、BISON、BYACC、BEG。CUP、Jell等Java語言開發(fā)的語法分析器生成器,可以生成Java語言描述的語法分析器。ANTLR是一種用Java開發(fā)的強大的語法分析器生成工具,可以生成各種語言描述的語法分析器,包括Ada、C、C#、Java、JavaScript、Objective-C等,以及Perl、Python和Ruby等較新的互聯(lián)網(wǎng)程序語言和腳本語言,甚至包括SQL、一階邏輯、XPath等應(yīng)用語言等。ACCENT則是一個包含了詞法分析器和語法分析器的生成工具。JavaCC是當(dāng)前應(yīng)用非常廣的一種語法分析器生成工具,能產(chǎn)生Java語言描述的LL(K)分析程序。值得一提的是,目前已經(jīng)有非常多的利用JavaCC開發(fā)的各種語言的分析程序,包括了表達(dá)式等簡單語言,如DTD、IDL、RTF等應(yīng)用語言,以及PHP等實用的腳本語言。隨著技術(shù)的發(fā)展,甚至出現(xiàn)了OOPS等面向?qū)ο蟮姆治銎魃晒ぞ摺?/p>
3)編譯前端。
面向c語言的中間代碼生成工具最著名的是Ckit,它支持將c語言程序翻譯譯成SML類型的中間語言,也支持用戶擴(kuò)展C語言語法的前端編譯。EDG則能將C++和Java等語言翻譯成一種高級的樹結(jié)構(gòu)中間語言,并具有錯誤檢查功能。在面向Java語言方面,比較知名的編譯器前端包括Jfront等。此外,為滿足特定應(yīng)用場景需求,還出現(xiàn)了IDC-C、SUIF等編譯前端及中間代碼優(yōu)化工具。
4)編譯后端。
編譯器后端方面的資源相對前端來說較少,比較知名的編譯器后端是BEG,以BEGL中間語言為輸入,可用于生成Motorola 68020、SPARC、MIPSl Intel 386、Pentium?Inmos T800和PowerPC等平臺的目標(biāo)代碼。在Java語言方面,Sable研究小組基于XML提出了JIL中間表示語言,利用XML的特性為執(zhí)行代碼的生成和優(yōu)化提供便利。此外,還有Trimam等針對并行環(huán)境生成執(zhí)行代碼并優(yōu)化的后端編譯器生成器等工具。
5)程序分析及代碼優(yōu)化。
在程序分析及代碼優(yōu)化方面的編譯工具較多,如BANSHEE、CodeSurfer、Omega、OOPS、PAG、SOOT等。其中BANSHEE、CodeSurfer、Kimwitu、MEMPHIS、PAG等工具針對C/C++程序進(jìn)行分析,Omega、PAT等工具則可以對Fortran、Java程序進(jìn)行分析,SOOT、OOPS提供了對Java等語言編譯器的優(yōu)化,上文中提到的Trimam及SUIF等則針對并行環(huán)境進(jìn)行了代碼優(yōu)化。
6)編譯器平臺。
除上述實現(xiàn)了部分編譯模塊的開發(fā)工具之外,還存在著大量實現(xiàn)了從詞法分析、語法分析直至最后目標(biāo)代碼生成所有環(huán)節(jié)的編譯器平臺資源,這些資源用于案例教學(xué)可以幫助學(xué)生對編譯的全過程進(jìn)行一個整體的理解和把握。這些平臺可以分為兩類:一類是以精簡語言為源語言的小型編譯器,如PL語言(PASCAL子集)編譯器、與ADA和PASCAL類似的TINY編譯器,以及斯坦福大學(xué)開發(fā)的COOL(The Classroom ObiectOriented Language)編譯器,這些編譯器都是面向?qū)iT為教學(xué)設(shè)計的某種精簡的編程語言,將其翻譯成某種抽象機代碼,借助抽象機解釋器執(zhí)行;另一類是以GCC、LCC為代表的產(chǎn)品級開源編譯器,面向C/C++這類主流的編程語言,提供開源、實用的編譯程序。
3.編譯資源在課程教學(xué)中的應(yīng)用
通過上面的分析,我們看到編譯開發(fā)工具和相關(guān)案例是非常豐富的,但是如何將這些工具和案例很好地結(jié)合到教學(xué)中,則需要做仔細(xì)的選擇和考慮。不論從課程教學(xué),還是實踐教學(xué)來看,編譯原理課程的學(xué)習(xí)可以從局部知識點和系統(tǒng)整體兩個層次開展。課程教學(xué)需要在掌握編譯各階段的具體知識點的基礎(chǔ)上,加強各知識點之間的融會貫通,并恰當(dāng)及時地從局部向系統(tǒng)整體引申。
在詞法分析、語法分析、語義分析、優(yōu)化、目標(biāo)代碼生成等知識點的學(xué)習(xí)過程中,可以引人相應(yīng)模塊的開發(fā)工具作為案例。如在講解詞法分析時可以結(jié)合LEX、在講解自上而下分析時結(jié)合JavaCC、講解自下而上分析時結(jié)合BISON,甚至可以在課堂教學(xué)時展示這些工具的核心代碼,加深學(xué)生對相關(guān)算法的印象。也可以在課外安排實踐作業(yè),要求學(xué)生選擇這些工具提供的案例資源,以已有的案例為基礎(chǔ)(為調(diào)動學(xué)習(xí)興趣,可以有意識地選擇學(xué)生在其他課程中已經(jīng)熟悉的語言,如數(shù)據(jù)庫中的SQL、操作系統(tǒng)中的Shell命令語言、離散數(shù)學(xué)中的謂詞邏輯等),實際生成一個編譯模塊,閱讀分析生成程序,在此基礎(chǔ)上,可要求學(xué)生擴(kuò)展原有案例。通過結(jié)合這些工具講解理論知識,并通過實踐作業(yè),使得學(xué)生能夠理解局部知識點,并掌握相關(guān)成熟的工具的使用。
在系統(tǒng)開發(fā)層面,編譯程序的開發(fā)是一個典型復(fù)雜的軟件開發(fā)任務(wù)。如果能在理解局部知識點的基礎(chǔ)上,為學(xué)生提供一個理解編譯程序整體全貌的平臺,以編譯過程為指導(dǎo)帶動課程知識點的學(xué)習(xí),也是非常有益的。如何在編譯程序的功能實用性和教學(xué)可用性兩方面保持平衡,一直是編譯教學(xué)的難題。開展綜合性實驗,是提高學(xué)生對編譯程序整體理解和開發(fā)能力的主要途徑。在這方面,有兩種思路。一種是側(cè)重整體體驗,主要是面向一個為教學(xué)而專門設(shè)計的精簡語言,如前文介紹的PL、TINY和COOL等,這些語言通常包含現(xiàn)代程序設(shè)計語言典型成分,但更為精簡,學(xué)生可以通過課程學(xué)習(xí),最后為該語言實現(xiàn)一個完整的編譯器。按照這種方案開展綜合性實驗,有利于學(xué)生體驗一個完整的編譯程序開發(fā)過程。第二種思路側(cè)重實用性和真實性,主要以GCC、LCC這類實用的,甚至是產(chǎn)品級的開源編譯器為平臺開展實踐。由于GCC、LCC這類實用編譯程序代碼量非常大,如何引導(dǎo)學(xué)生在紛繁復(fù)雜的代碼中理清頭緒、找到和教學(xué)知識點相關(guān)的程序段,需要教師做好充分的準(zhǔn)備。這種思路,對于將來從事編譯程序開發(fā)的學(xué)生,其收獲可能更大。
4.結(jié)語
理論和實踐的完美結(jié)合是編譯程序研制的突出特點,也是編譯課程教學(xué)力圖為學(xué)生展示的特色。為了使學(xué)生切實體驗編譯經(jīng)典理論在編譯程序研制以及其他領(lǐng)域發(fā)揮重要作用,我們收集了一批編譯開發(fā)工具,并對這些資源從公開程度、開發(fā)語言、生成語言、系統(tǒng)平臺、涉及課程知識點、應(yīng)用領(lǐng)域和是否提供案例等方面進(jìn)行分析和標(biāo)注。到目前為止,已收集60余項軟件工具資源,并在課程網(wǎng)站上發(fā)布。下一步,我們將繼續(xù)擴(kuò)大收集編譯資源的規(guī)模,并進(jìn)一步提高分析和標(biāo)注的準(zhǔn)確性,積極探索如何結(jié)合這些資源開展課堂教學(xué)和實踐教學(xué)改革,利用這些資源向?qū)W生展示編譯研究中“經(jīng)典理論和先進(jìn)技術(shù)有機結(jié)合”的突出特點,并使學(xué)生切實體驗編譯經(jīng)典理論在各領(lǐng)域的重要作用,培養(yǎng)學(xué)生的計算思維,提高課程教學(xué)的效果。