张 莉 杨海燕 史晓华
摘要:“编译技术”是一门公认的难教难学的课程,包含了看似晦涩的理论部分和覆盖面广的实践部分。如何根据本学校的培养定位组织教学内容,如何实施教学过程,是教师们普遍关注的主要问题。本文结合北京航空航天大学这类工科院校强调工程技术的特点,探讨了“编译技术”课程的组织方式,提出了以编译过程为主导带动课程知识点的课程安排模式,并针对不同类型高校给出了教学安排建议。
关键词:编译技术;编译原理;课程定位;课程内容组织
中图分类号: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.