邵兵
摘要:軟件學院對學生的培養(yǎng)目標集中體現(xiàn)在“實用”上面,因此對傳授計算機基礎理論知識的編譯原理課程必須加大實踐環(huán)節(jié)的側(cè)重。如何在傳授理論知識的同時,大力培養(yǎng)學生的編程能力,一直是擺在各軟件學院面前的一道難題。文章針對這一現(xiàn)實問題,通過分析學生的接受能力,有針對性地設計幾種課程實踐的實施方案,并說明北京航空航天大學軟件學院編譯原理課程教學中的實踐情況和取得的效果。
關(guān)鍵詞:編譯原理;編譯技術(shù);課程實踐;編程能力
1 軟件學院編譯原理課程實踐環(huán)節(jié)的重要性
隨著本科生招生人數(shù)的大幅增加,高校畢業(yè)生就業(yè)競爭加劇,用人單位對人才要求不斷提高,計算機及相關(guān)專業(yè)的不少畢業(yè)生在就業(yè)過程中暴露出動手能力差、分析問題解決問題能力薄弱、創(chuàng)新意識不強等問題。這些問題的出現(xiàn)在很大程度上反映出高校在學科的專業(yè)實踐(特別是課程實踐)教學方面的不足。作為大學課程中第一個較為系統(tǒng)化的軟件設計類課程實踐,編譯原理實踐對培養(yǎng)學生動手能力無疑起著非常重要的作用。
編譯原理(在有些學校稱為編譯技術(shù))是本科計算機專業(yè)的一門重要專業(yè)基礎課程,也是計算機系統(tǒng)軟件中非常重要的一個分支,其理論性和實踐性都很強。大部分高校在這門課程的開設中,都會將其劃分為理論講授和課程實踐兩部分進行實施,甚至將理論講授和課程實踐分列為兩門課程。
2002年,教育部在成立示范性軟件學院的批示中,將“軟件學院要培養(yǎng)市場急需的‘實用型人才”放在了比較重要的位置,這也構(gòu)成了軟件學院區(qū)別于傳統(tǒng)計算機學院的重要標志。因此對于軟件學院的學生而言,編譯原理的教學情況則有所不同。首先,軟件學院的歷史都不長,受課時和師資等多方面因素的影響,一些學校甚至是示范性軟件學院,也會將該課程壓縮甚至完全砍掉;其次,即使是保留該課程教學的學校,也會不同程度地壓縮實踐環(huán)節(jié)的時間,多多少少地影響到學生對編譯技術(shù)的理解與掌握。筆者認為,盡管編譯原理課程確實存在理論抽象、概念眾多、算法多等特點,但這門課程對于培養(yǎng)學生掌握構(gòu)造高級程序設計語言、編譯程序的基本原理、結(jié)構(gòu)、設計與實現(xiàn)技術(shù),培養(yǎng)學生了解和掌握編譯原理的基本原理及典型技術(shù)并具備相當?shù)膽媚芰Γ瑤椭鷮W生為今后從事軟件開發(fā)打下堅實的理論基礎,提升學生程序設計能力和創(chuàng)新能力等諸多方面,都有著其他課程不可替代的作用。因此編譯原理課程教學不但不應該削弱,反而應該受到重視和加強。
在此前提下,如何讓軟件學院的學生在掌握編譯技術(shù)基本原理的同時,大力加強他們對編譯技術(shù)的理解與使用,從而提高其產(chǎn)品——計算機軟件(尤其是大型軟件)的結(jié)構(gòu)有效性和效率,則是擺在軟件學院編譯原理課程教學的—個重要問題。
2 對學生能力的分析
在各高校的軟件學院中,普遍存在著生源參差不齊的現(xiàn)象。由于學生入學時對計算機軟件了解不多,所以即使是在示范性軟件學院,也有相當一部分學生入學時對軟件專業(yè)的認識不夠,大學階段的頭兩年如果沒有打下良好的基礎,則直接導致對專業(yè)課的畏懼乃至厭學情緒。所以在對學生傳授知識和培養(yǎng)能力時,更需要摸清學生基礎,培養(yǎng)他們學習興趣,通過加強實驗和實踐環(huán)節(jié),培育其分析問題和解決問題的能力。
通過觀察和調(diào)研可知,軟件學院的學生大致上可以分為以下幾類:一是對計算機知識很感興趣,且學習能力較強的學生;二是對計算機知識的興趣一般,且學習能力平常的學生;三是對計算機知識不感興趣,且學習較差的學生。
像北航這樣985高校的軟件學院中,學生的學習能力普遍比較高,學校給學生提供的實驗環(huán)境和配備的師資力量也普遍較強,因此比較容易形成良性循環(huán),為課程教學和實驗教學提供重要的基礎保障。但根據(jù)歷年編譯原理期末考試的情況分析看,實際教學效果也并非完全符合正態(tài)分布。高分段(>85分)學生的人數(shù)相對較多,約占40-50%左右,且這部分學生的能力較強,即使適當加大試題難度對其考試分數(shù)的影響也比較小;而不及格學生的人數(shù)大約占10%左右,且即使降低試題難度對其影響也較??;試題難度影響較大的是中間段的學生。
對學生的接受能力有一個正確的了解,才能有針對性地因材施教,使編譯原理的實踐環(huán)節(jié)達到應有的效果。
3 因材施教
筆者在編譯原理與實踐課程教學過程中,嘗試過不同的實踐方式。通過不斷地摸索,發(fā)現(xiàn)采用如下的因材施教方式效果最佳。
(1)對于學習能力較強的學生,可以讓他們自己動手編寫小型編譯器。一個完整的編譯器包含詞法分析、語法分析、語義分析、中間代碼生成和代碼優(yōu)化等前端部分,也可以包含生成和具體計算機體系結(jié)構(gòu)相適應的可執(zhí)行代碼后端。一般編譯原理實踐環(huán)節(jié)大多安排學時為32學時左右,因此要讓一個(或一組)學生在這么短的時間內(nèi)完成前端和后端兩部分是不現(xiàn)實的,可以讓學生單獨完成前端。
(2)對于學習能力一般的學生,在實施編譯程序?qū)嵺`教學中,除了可以采用第一種方法外,還可以讓他們利用LEX、YACC、JavaCC等工具來編寫編譯器。由于YACC等語法分析程序是基于自底向上的分析方法,所以在編譯原理課程教學環(huán)節(jié),對LL等分析法就應當賦予較多的時間和精力,力爭讓學生在使用這些工具生成編譯器程序時,清晰地了解它們的工作原理。
(3)對于學習能力相對較弱的學生,可以采用分析現(xiàn)有編譯器程序的方法。也就是說,并不要求他們自己去設計開發(fā)一個具體的編譯器,而是通過讀懂現(xiàn)有的編譯程序,了解其工作原理。哪怕讓他們比葫蘆畫瓢地逐行輸入并調(diào)試現(xiàn)有的程序,找出現(xiàn)有程序中的印刷錯誤和不合理之處,都對其動手能力的提升起到一定的作用。具體編譯程序可選擇PL/0文法程序代碼,或者是Pascal-S文法程序代碼。當然,其他類似的編譯器程序都可選用。
還可以提供給學生不完整的程序源代碼,讓其采用填空的方式完成其中部分關(guān)鍵模塊。此類題目由于提供了大部分源程序,只是讓學生參考教材或課堂上的例子集中精力解決一些關(guān)鍵問題,這樣就能保證大多數(shù)學生都能完成實踐任務,真正達到讓學生通過課程實踐加深對編譯過程理解的目的;同時學生在編譯器的實現(xiàn)過程中也能夠產(chǎn)生成就感,從而消除了對課程的恐懼感,增加學習的信心。
在對編譯源程序的選擇上,可以選取循序漸進的指導思想,例如張晶等人提出的Lo文法就只包含了空語句、賦值語句、條件語句和循環(huán)語句等基本語法成分??梢宰寣W生在此文法基礎上使用相對簡單的遞歸下降分析法先進行實現(xiàn),完成后再逐步對其進行擴充。這種方法就像軟件工程中的原型開發(fā)方法,有利于學生快速看到自己的成果,從而樹立信心,取得預計的效果。如果擴充的文法只是同一種類型的簡單擴張,則學生會陷入重復的勞動,從而讓他失去興趣,所以文法的擴充一定是方法的擴充。
對于部分學生,還可以讓其利用所學知識編寫類編譯器的工具,比如智能編輯器、公式編輯器等。只要是能夠?qū)⒕幾g技術(shù)的知識用到具體程序中去,所有的嘗試都應當予以鼓勵,但這種嘗試一定要在老師的指導和監(jiān)督下進行,以免出現(xiàn)學生出發(fā)點雖好,但遇到具體技術(shù)問題無法克服進而導致挫折性失敗的情況。
4 編譯原理實踐教學的時機
通過對不同學校的調(diào)查發(fā)現(xiàn),不同的學校對編譯原理實踐教學環(huán)節(jié)的安排主要有以下兩種情況。一種是將教學環(huán)節(jié)和實踐環(huán)節(jié)完全分開,而且分別放置到兩個學期中實施。這種方法雖然存在著界限分明、便于組織教學的好處,但實踐證明由于理論和實踐嚴重割裂,學生往往在第二個學期實踐環(huán)節(jié)中對上一學期所學的知識遺忘得非常厲害,導致教學效果很差,因此不建議采用;另外一種稍好的方法,是將教學和實踐環(huán)節(jié)雖然分開,也就是先進行課程教學,結(jié)束后再進行實踐。這種方法雖然把兩個環(huán)節(jié)放在一個學期實施,解決了理論和實踐脫節(jié)的矛盾,但上述矛盾依然存在,只是理論和實踐脫節(jié)的程度稍輕一些而已。
經(jīng)過多年的實踐,作者認為采用兩遍教學法可以較好地解決這個問題。也就是說,把教學和實踐放在同一個學期實施,不要將它們完全分開。首先可以講授編譯原理的最基礎知識,例如詞法分析、語法分析中的自頂向下分析法、語法制導的語義分析等,與此同時安排學生進行編譯器相應部分的編寫工作,即把整個實踐環(huán)節(jié)變成教學環(huán)節(jié)的一個大作業(yè)。待學生完成后,再進一步講解詞法分析中自動機理論、語法分析中的LL及LR分析法、代碼優(yōu)化以及目標代碼生成等內(nèi)容,最后再完成利用編譯工具進行編譯器自動生成的實踐。在這種教學方法中,課堂教學和實踐環(huán)節(jié)交叉進行,學生學到哪里就實踐到哪里,從而保證教學與實踐的緊密結(jié)合。
5 結(jié)語
筆者在北航軟件學院七年的教學實踐中,通過對學生學習能力的調(diào)查分析,摸索出了在教學過程中首先區(qū)分教學對象,然后因材施教的基本思路,并給出了具體的解決方案。
首先,在頭幾年的教學中采用的是簡單的統(tǒng)一式實踐方式,即所有學生采用同一個題目、使用同一種文法,獨立完成一個編譯器前段。此時有大約五分之一的學生存在偷懶抄襲別人作業(yè)的現(xiàn)象。之后采用分題目實踐方式,即自我感覺水平較高的同學經(jīng)過申請可以采用CO文法,絕大部分同學使用PL0文法獨立完成一個編譯器前段;自我感覺水平較低的同學采用在部分已有Pascal-S文法基本模塊的基礎上,通過填空補充遞歸子程序語法分析模塊。此時沒有發(fā)現(xiàn)學生抄襲別人代碼的現(xiàn)象。為了保證成績的區(qū)分度,所有獲得優(yōu)秀(采用五級計分制)的學生必須參加答辯,經(jīng)過代碼講解和演示并通過教師提供的測試。
改革后學生們普遍反映“通過大作業(yè),對課本上的知識有了更深刻的認識”、“編譯原理課程是我大學四年學過的最難課程,其中編譯實踐對我的幫助最大”。2015年一位同學更是由于在其博客中發(fā)表了對LLVM編譯相關(guān)的研究內(nèi)容,被美國加州大學河濱分校的一位華人教授發(fā)現(xiàn),并表達了招收其為直博研究生的意愿。
事實上,北航軟件學院的編譯原理課程近幾年也經(jīng)歷了由必修課程改為選修課程,又由選修改為必修的曲折道路。在課程性質(zhì)為選修的時候,編譯原理和編譯實踐是分割到兩個學期的兩門獨立課程。一部分學生由于種種原理,在選修過編譯原理課程后不愿意再選修編譯實踐,導致對相關(guān)知識的掌握只是停留在表面。后來我們采用前述的兩遍教學法,將編譯原理和編譯實踐有機地融合到了一個學期,從而保證通過實踐環(huán)節(jié)對課堂上所學的理論知識有較深的理解,達到了提高教學效果的目的。
(編輯:史志偉)