基于Java的编译原理课程案例教学方法初探
摘要:针对编译原理教学实际,在分析和修改工业级开源编译器实现代码的基础上,提出一个基于Java的编译原理课程案例教学过程,结合Java这种日益普及的面向对象程序设计语言,这种教学过程在编译原理课程教学方面取得良好效果。
关键词:Java字节码;Java类文件;Javac;Java编译器;编译原理
编译原理是计算机与软件专业的核心基础课程,是关联汇编语言程序设计、高级语言程序设计等相关课程的纽带。如何深入进行编译原理课程教学改革,更好地帮助学生理解和掌握编译器的设计原理与基本实现方法,更好地在教学过程中体现计算机软件核心思想,更好地依托一个载体紧密结合工程实践与理论研究,是新时期编译原理课程教学面临的挑战。
1案例教学在编译原理中的作用
1.1编译原理课程的内容组织
编译原理在软件学科中占据核心位置,起着重要作用。编译原理包括词法分析、语法分析、语
义分析和中间代码生成、代码优化、运行时存储组织等[1]。除了上述基本知识点外,了解编译原理在现实世界中的广泛应用,知道编译器在计算机与软件专业课程体系中的关键地位,是激发学生认真学习和掌握本门课程基础知识及专业工具的有效手段。
1.2案例教学的作用
为了更有效地组织编译原理课程的教学工作,避免传统式教育存在的“重基础、轻实践”的弊端[2],针对新时期研究型大学本科生的特点,我们提出了如下基于主流编译器的编译原理课程案例教学方法:先让学生对编译原理课程的教学载体,即一个较为完整的编译器,建立初步认识,再借助学生较强的自学能力和动手能力,在实践中学习和体会程序设计语言编译过程的基本原理,切实保证理论联系实践,尤其是强调“学中练、练中学;练中闯、练中创”[3]。首先让学生了解一个典型编译器的输入和输出,同时通过图形化方式使得学生对编译过程的主要阶段建立感性认识;进而熟悉作为课程载体的一个编译器原型,并对其进行改造;最终达到学习编译原理基础知识,并对规范化程序设计有所深入理解的目的。
2基于Java的编译原理案例实验设计
作为一个主流的面向对象程序设计语言,Java已经占据了近20%的份额[4],在计算机网络等应用中起着越来越重要的作用,不仅覆盖了从大型网络应用系统开发到SIM卡芯片上的认证程序等大量应用,而且保持着强劲的发展势头。鉴于此,本课程考虑基于Java的编译原理案例教学。
2.1实验设计
基于Java的编译原理实验包括了解实验目标和进行具体实验操作两阶段。实验目标包括源、目的和转换过程三部分,分别涉及对源语言(Java程序设计语言)的理解,对目标语言(Java类文件,包括Java字节码)的理解,和对编译过程的理解。鉴于前导课程Java语言程序设计已充分介绍了Java源程序,本课程主要介绍后两部分。
具体的实验操作可以细分三个层面。一为使用现有词法器/语法器的自动生成工具(如JLex、CUP)实现一个Java编译器,二为依据编译原理的基础理论手工设计实现一个Java编译器,三为构造词法器/语法器等程序的自动生成工具,并基于这些工具实现Java编译器。可根据具体教学情况侧重某一层面。
2.2Java类文件的讲授
Java类文件包含常量池、接口表、域表、方法表和属性表等信息。Java字节码是Java类文件的关键组成部分,字节码序列出现在方法的Code属性项中。为了让学生了解Java源程序的编译过程,并掌握Java类文件的结构,采用如下案例。首先给出一个简单的Java源文件然后将上述文件编译为Java类文件,并通过“javap –c Act”命令展示对应的字节码序列,并向学生予以讲解。接着,按十六进制打印输出Act.class文件(如图1所示),并在课堂上作为补充材料发给学生。
进一步地,我们通过一个Java Applet程序(如图2所示)向学生逐步展示Java虚拟机是如何以流的方式单步装载图1中的大学编程课是学什么的Java类文件的[5]150,并在补充材料上予以标注学习。
2.3Java编译过程的图形化展示
在讲解编译过程时,充分考虑以图形化方法展示关键步骤,使学生们能够首先建立感性认识,进而研讨具体的编译算法并为此制作一些演示程序。例如,我们通过prefuse工具,制作了从源程序到词法单元(token)流的映射过程。对于输入的一段Java源程序,可以形象地以树的方式展示其对应的token集合。如图3所示,对应左侧窗口的一个Java源程序,在右侧窗口出现一个词法单元序列。除了注释符和空白符号外,源文件中的每个词素都对应一个词法单
元,包括词法单元名字和属性值。
在语法分析过程中,也通过可视化的方式将一个语句块及其对应的树状结构予以形象表达。如图4所示,对应左侧的一个语句块,在右侧以图形化的方式表达出一个树状结构。
3基于Java的编译原理案例教学实践
为了更好地讲授编译器的设计与实现,以一个设计良好的工业级编译器Javac为课程案例,展示编译器的设计原理与实现方法。课堂上剖析的对象是OpenJDK中的Javac编译器[6]。
3.1Javac的结构及特点
OpenJDK中的编译器Javac包括137个java文件。其重要的类和包如表1所示。
Javac使用的是LL(1)递归下降分析方法,同时使用算符优先分析方法对二元运算表达式进行分析。Javac具有模块清晰、代码风格统一、注释完善等优点,并且使用了大量典型的设计模式。
当然,Javac编译器的源代码也存在一些不足,例如没有充分应用代码优化技术。但是,考
虑到本科编译原理教学的重点一般是词法分析和语法分析,使用Javac在现阶段还是可行的。此外,学生可以通过其它方式来学习和掌握一定的代码优化技术。
3.2Javac的教学实践
在词法分析阶段,学生的任务是分析输入的Java源程序并生成对应的token流。在语法分析阶段,学生的任务是用CUP工具生成LALR(1)语法分析器,并将其集成入Javac。其关键步骤是在ls. javac.parser.ParserFactory中重写newParser方法,实现语法分析器的替换。具体如下所示:
public Parser newParser(CharSequenceinput, booleankeep DocComments, booleankeepEndPos, booleankeepLineMap)
{
…
MyScanner lexer= wScanner(input);
return new MyParser(lexer);
…
}
此外,还可以考虑向现有Javac中引入新的语法结构,例如实现变量类型的自动推断,并以此来进行语义分析方面的实验。
4考评及讨论
4.1考评制度
考评是巩固课程教学效果的重要措施,是教学过程中的一个关键环节。我们认为,课程考评的对象不仅是学生,还包括教师。在编译原理案例教学过程中,对教师采用引导考评与主动考评相结合的方式,对学生采用个体及分组考评的方式。在引导考评部分,学校提供三种考量手段,一是期末学生评教活动。在期末考试前,由学生对任课教师给予定性及定量评价,包括从“作业等课程训练有利于课程内容的学习”等10个角度进行量化评价,并参与全校本科
生理论课程的排名,同时给出学生个人的具体意见。二是干部听课制度。在每学期的第6~7周,学校、学院领导及班主任等随机选取课程听取,并与选课同学交互,形成书面意见。三是督导制度。学校组织教学督导组不定期抽查教学情况。在自我考评部分,一方面通过书面形式,在课堂上多次请同学们给出改进建议,另一方面采取座谈形式,通过班级干部邀请对编译原理课程建设感兴趣的学生座谈,以了解学生的学习心理和学习动态。
对学生的考评由课堂小测、课后作业、大作业和期末考试等几部分构成。其中,大作业采取分组考评方式,其他考评由个人独立完成。具体的,本课程的大作业考评包括按组进行的代码实现和口头答辩两个环节。每组学生不多于3人,通过分组以进一步提高学生的团队交流和沟通能力。与课堂教学工作相配合,大作业代码实现分阶段推进,助教在每阶段结束前发布项目测试文件。在大作业答辩环节,要求学生讲出本组工作的创新点,以克服工科学生常见的表达能力欠佳的现象,增强学生的总结能力与表达能力。
此外,除了考前安排答疑,我们还通过在课余设置日常答疑时间,尤其是在讲授语法分析、语义分析等较难知识点之后,鼓励学生把知识的掌握与消化过程放在平时。在实验答疑方面,助教会定时与学生沟通。
4.2讨论
是否可以采用非Java的编译器?传统上,编译原理的教学过程多采用C编译器。本课程考虑使用Java相关编译器的原因在于:1)面向对象程序设计语言已经成为计算机程序设计语言的主流。Java语言是面向对象程序设计语言的典范,具有广泛应用。学生对于Java语言编译过程的良好理解,有助于他们对其余面向对象程序设计语言编译过程的了解。2)常用的课堂教学用编译器,如C编译器,如果是完整版本,其底层和硬件相关程度较大,不便于教学;如果是简化版本,则学生在理解整个过程中会有所不足。
是否必须用OpenJDK中的Javac作为案例?可以在教学中使用其他Java编译器,例如GCJ。在已有的若干Java开源编译器中,OpenJDK中的Javac编译器结构优美,设计良好,融合了若干经典设计模式,并且注释全面。通过阅读Javac源代码,不仅可以帮助学生理解和掌握编译器的实现过程,而且有助于学生加深对于软件工程的理解,提高代码编写质量。此外,学生还可以进一步阅读关于JRE的其它代码,了解Java虚拟机的工作原理。因此,本课程目前采用OpenJDK中的工业级开源Java编译器Javac作为课程案例教学载体。
是否考虑让学生自己写一个编译器,而不是去阅读一个编译器?这与阅读Javac源代码并不
矛盾。学生可以在阅读理解Javac源代码的基础上,进一步修改其代码。例如在本课程中,学生会被要求用自下而上的语法分析方法来替换Javac中原有的自上而下的语法分析方法。学生还可以在控制语句转换等方法进一步实现更好的机制。
5结语
以上是笔者在清华大学软件学院讲授编译原理课程5年来的一些经验总结。今后,我们还要结合具体情况,对教学过程不断进行改革和调整,包括引入阶段式综合考评,设计增加课程研讨环节等,以期进一步激发学生的求知欲,更好地理解和掌握编译原理。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论