图书前言

自Fischer和LeBlanc合著的《编译器构造》(Crafting a Compiler)一书于1988年出版以来,这个世界已经发生了巨大的变化。虽然有些老师可能还会记得,该课本所附软件使用的5.25寸软盘,而今的大多数学生则可能根本没见过或者没有接触过这样的磁盘。学生们在课堂上和实践中所遇到的编程语言也发生了巨大的变化。在1991年的时候,该教材划分出了两个版本,分别使用了C和Ada两种语言来描述其中的算法。虽然C依然是一种很流行的语言,但是Ada并没有达到预期的广泛应用,已经逐渐淡出了人们的视线。从C语言派生出添加了面向对象特性的C++语言。Java则是一种更为简单的面向对象语言,由于其安全性以及可以在Web浏览器中运行而得以广泛流行。美国大学预修课程(College Board Advanced Placement)中使用的编程语言已经从Pascal转为C++,现在又转向了Java。

虽然大环境发生了很大的变化,但是众多学生和教师还是在继续学习和讲授编译器构造的相关课程。在编译器和程序设计语言翻译领域的研究工作也依然在持续增长,这是由于为了适应日益增加的体系结构和编程语言的种类,编译器被赋予了更加重要的使命。软件开发环境通用要依赖编译器来同各种不同的工具链构件进行交互,其中包括语法指示的编辑器、性能刻画工具(profiler)和调试器等。所有现代软件项目都要依赖于编译器对程序中的错误进行严格检查,并且做到对程序进行如实的翻译。

有些教材随着时间会做一些较小的改动,例如添加一些新的练习或者示例。与1988年和1991年的版本相比,本书则进行了非常显著的修订。虽然本教材的关注点依然是讲授编译器构造的基本知识,但是其中的算法和解决方案都采用了更为现代的方式:

* 对有些在实践中很少再使用的内容(例如,属性文法)采取了最小化处理,甚至全部去掉。

* 书中的算法采用了一种伪码(pseudocode)风格来展示,凡是学习过计算机学科基本算法的同学都应当会比较熟悉这种风格。伪码可以用来简洁地描述一个算法,并且支持对该算法的目的和结构进行合理的讨论。

使用某种特定语言的实现细节则被放到了网上可以下载的补充材料中,网址是http://www.pearsonhighered.com/fischer。

* 本书关于语法分析的理论和实践的组织可以支持各种不同的教学方法。

有些读者可以从高层来学习这些内容以得到关于自顶向下和自底向上分析的高级视图。另外一些读者则可以选择更加详细地学习一种特定的方法。

* 编译器的前端和后端之间是通过抽象语法树(Abstract Syntax Tree, AST)连接起来的,抽象语法树是在分析过程中创建的主要制品。大多数编译器都会构造抽象语法树,但是很少有教材清楚地讲解它的构造和使用方法。

本教材还引入了访问者模式(visitor pattern),用来在语义分析和代码生成的过程中对抽象语法树进行遍历。

* 教师可以获取关于实验和上机的练习题。

教师也可以把其中的某些部分布置为学生的练习,而其他内容则可以从课程支持网站中获取。

有些教材在修订的时候添加了更多研究生阶段的内容。虽然这些内容也会有助于开设一门高级课程,但是本教材的关注点依然是大学本科阶段要学习的编译器构造知识。研究生课程可以使用本书的第13章和第14章,而把教材的前面部分当做参考资料。

教材与参考资料

作为一本教材,本书是作者用过去25年时间精心建设的一门课程。本书的使用可以非常灵活,它曾经被用于在10周的短学期中讲授的三学分的高阶课程,也曾用于六学分的长学期中讲授的研究生课程。本教材适用于对于编程、算法和数据结构拥有基本背景的任何学生。本书的结构非常灵活,因此教师可以根据需要来构造一个短学期或长学期的教学大纲。对于那些没有详细讲解的内容,则可以为学生提供作者的解答。使用本教材,在一个学期内完成编译器中从分析到代码生成部分的编写工作是完全可行的。

本书也可以作为很好的专业参考书,因为它覆盖了对于编译器构造来说实际上最为重要的所有技术。我们的许多学生即使在他们毕业很多年之后,还会在他们工作中遇到本书中讲到的技术。

教 师 资 源

本书的网站地址是http://www.pearsonhighered.com/fischer。网站上给符合资格的教师提供的内容包括示例的实验和项目作业布置,上机(主动学习)练习,可以被用作课程提供解答的代码库,以及部分练习的参考答案。

要想访问这些材料,有资格的教师应当访问http://www.pearsonhighered.com,发邮件给computing@aw.com,或者访问http://www.pearsonhighered.com/irc/上的Pearson教师资源中心(Instructor Resource Center),来联系其当地的Pearson代表。

学 生 资 源

本书的网站http://www.pearsonhighered.com/fischer上包含本书中使用的示例的所有可执行的代码,其中也包括了在第2章中讲到的玩具语言ac的代码。该网站还包含了一些讲义资料,另外还有一个网页上提供了不同编译构造工具的链接。

编程实习的方案

本书提供了编译器构造中相关理论知识的全面讲解。然而,通常来说在规划编译器构造课程时很重要的一个方面是设计一个与之结合的编程实现项目。因此,本书以及在线资料都更倾向于一系列探索性的练习,最终形成一个项目,来支持对这些内容的学习。

本书补充材料中会包含实验练习、上机讲解和课程项目等内容;我们也欢迎读者发给我们其他材料或者链接,这些可以粘贴到我们的网站上。这些练习与教材中讲解的章节和内容进度保持同步。例如,第2章引入了玩具语言ac来概要讲解编译过程。网站上也包含了该语言对应的扫描器、分析器、语义分析器和代码生成器的完整、可运行的版本。这些组件中都包含用不同源编程语言书写的版本。

网站上还提供了为一个类Java的简单语言开发可用的编译器所需的支持材料。这样教师就可以选择把其中一些组件作为练习来布置,而把其余组件直接提供给学生填补其中的缺口。有些教师也可以选择提供整个编译器,而要求学生对其进行扩展。对现有组件进行润色和细化也可以作为课程项目的基础。

伪码和指引表

与老版本的教材相比,本书的一个重要变化是:书中的算法不再使用任何具体的程序设计语言(例如C或Ada)来展现。作为替代,算法使用了一种伪码(pseudocode)形式,这种形式对于所有学过最基本算法 [CLRS01] 的读者来说应当都会比较熟悉。伪码通过略去不必要的细节而简化对算法的阐释。然而,伪码中暗含了在真实程序设计语言中使用的结构,所以实现起来会相当容易。在本书最后会为书中出现的所有伪码函数提供一个指引表(guide)。

本教材中大量使用了缩写(包括首字母缩略词)来简化对问题的阐述,并帮助读者了解在编译器构造中经常使用的术语。在每章中首次出现每个缩写的时候,都会自动给出完整的定义。例如,AST已经在本前言中用到过(作为抽象语法树的缩写),但是上下文无关文法(context-free grammar, CFG)还没有用到。作为进一步的帮助,在本书最后把所有缩写的索引也做了一个指引表。完整的索引列表中也包含了这些缩写,并会说明它们在书中哪些地方用到。指引表中的术语会用粗体形式来表示。在完整的索引表中也会包括所有这些术语的每一次引用。

如何使用本书

关于编译器构造的介绍性课程可以先讲述第1~3章。对于语法分析技术,可以选择讲解自顶向下(第5章)或者自底向上(第6章)的内容,但是有些教师会选择两章内容都讲解。第4章中的内容可以作为支持所要讲解的分析技术的基础。第7章介绍抽象语法树,并引入用来对它进行遍历的访问者模式(visitor pattern)。有些教师可能会把管理抽象语法树的实用程序当做编程练习,而其他老师则可能会选择使用教材网站提供的实用程序。根据教师的选择,可以讲解第8~9章中关于语义分析的不同内容。如果是一个季度的课程,那么可能到这里就结束了;这样就需要用另外一个季度来讲解代码生成以后的内容(随后进行介绍)。

第10章提供了关于Java虚拟机(JVM)的简介,如果学生要在编程作业中生成JVM代码的话,那么就需要学习本章。第11章会讲解如何为这样的虚拟机进行代码生成。如果教师希望学生生成机器码的话,那么可以跳过第10章和第11章,而是讲解第12章和第13章。初级编译课程中可以包含第14章前面部分关于自动程序优化的部分内容。

更进一步的学习则可以包括在第4~6章中涉及的分析技术的更多细节。而第8章和第9章中的语义分析和类型检查也可以更加深入地进行讲解。还可以引入第10章和第14章中的更加高级的概念,例如静态单赋值(static single assignment,SSA)形式。教师还可以从第14章中找到关于程序分析和转换的高级内容(包括数据流框架在内)。第13章和第14章也可以作为研究生阶段的编译课程的基础,而把之前的章节作为有用的参考资料。

章 节 简 介

第1章  概述

本教材首先会简要介绍编译的过程,其中会强调使用一系列构件来构造编译器的概念。本章还介绍了编译器的历史,以及如何使用工具来生成编译器的这些构件。

第2章  一个简单的编译器

本章介绍一个简单的语言ac,以及用来把ac转换为另外一种语言dc的编译器构件。这些构件都是用伪码来介绍的,完整的代码可以从“《编译器构造》补充材料”中找到。

第3章  扫描--理论和实践

本章讲解用来构建词法分析构件的基本概念和技术,内容包括手工编码的扫描器,以及使用扫描器生成工具来实现表格驱动的词法分析器。

第4章  文法和分析

本章讲解形式语言的概念和基础,其中包括上下文无关文法、文法记号、推导和分析树。同时会引入在第5章和第6章中要用到的文法分析算法。

第5章  自顶向下分析

自顶向下分析是用来构造相对简单的分析器的常用技术。本章会讲解如何使用直接编码,或者通过给通用的自顶向下分析引擎构造一个表格来编写这样的分析器。本章还会讨论语法错误的诊断、恢复和改正。

第6章  自底向上分析

现代编程语言所使用的绝大多数编译器都会使用本章中讲解的某种自底向上的分析技术。读者可以很容易获得从一个上下文无关文法来自动生成这类分析器的工具。本章会讲解这些工具构造的理论基础,其中包括用在某些文法会产生阻碍分析器构造的冲突(conflict)时,为消除冲突所采用的一系列越来越复杂的解决方案。本章还会详细讨论文法和语言的二义性(ambiguity),并讲解用来理解和消除二义性文法的启发式方法。

第7章  语法制导翻译

按照编译器的组成构件来划分,本章是本教材的一个分水岭。前面的章节中涉及的都是程序的词法和语法分析。这些章节的目标是构造一个抽象语法树。在本章中会介绍AST,以及用来对AST进行构造、管理和遍历的一个接口。本章对于后续章节是至关重要的,因为它们会依赖于读者对于AST的理解,以及用来辅助对AST进行遍历和处理的访问者模式(visitor pattern)的理解。在“《编译器构造》补充材料”中包含关于访问者模式的一个教程,其中包括了从实践中抽取的一些实例。

第8章  符号表和声明处理

本章会着重介绍符号表的使用,它是在整个编译过程中都会用到的一个抽象构件。本章会为符号表定义一个准确的接口,并且讲解各种与实现相关的问题和想法,其中还会讨论如何实现嵌套的作用范围。

本章会讲解在处理符号声明的过程中必不可少的语义分析,包括类型、变量、数组、结构和枚举。另外,本章还会介绍类型检查,其中包括面向对象类、子类和超类。

第9章  语义分析

对于在分析过程中不能很容易检查的语言规范需要进行额外的语义分析。在这里会检查不同的控制结构,包括条件分支和循环。本章还讨论了异常(exception),以及在编译时它们要求进行的语义分析。

第10章  中间表示形式

本章会涉及编译器广泛使用的两种中间表示形式。第一种是JVM指令集和字节码形式,这已经成了用来表示经过编译的Java程序的标准格式。对于感兴趣在编译器项目中以JVM作为目标码的读者,第10章和第11章提供了必要的背景知识和技巧。另外一种表示是SSA形式,常用在很多优化编译器中。本章会定义SSA形式,但是它的构造会放到第14章中,等到我们把一些必要的定义和算法都讲解完之后介绍。

第11章  面向虚拟机的代码生成

本章讲解如何为虚拟机(virtual machine,VM)生成代码。考虑以虚拟机作为目标的优点是可以把许多运行时支持的细节都交给VM来承担。例如,大多数VM会提供不限数量的寄存器,从而就可以把寄存器分配(register allocation)推迟到掌握了代码生成的基础之后再进行。VM的指令集通常比机器代码要高级。例如,函数调用通常可以用单个VM指令来支持,而相同的调用在机器代码中则需要很多条指令。

如果读者热切期望了解如何生成机器代码的话,那么很可能想跳过第11章,但我们建议在为机器代码级别尝试生成代码之前先要学习本章。本章中的思想可以很容易就应用到第12章和第13章,但是从VM的角度来看它们更加容易理解。

第12章  运行时支持

VM内嵌的功能中大多都是它提供的运行时支持(例如,对存储管理的支持)。本章讨论为现代程序设计语言提供运行时支持所需的各种不同概念和实现策略。学习这些内容会提供对于VM构造的理解。对于那些希望为目标体系结构(第13章)生成机器代码的读者,运行时支持是必须要提供的,因此学习这些内容对于创建一个可用的编译器是至关重要的。

本章会讨论静态分配、栈式分配和堆式分配的存储形式。另外还会涉及对非本地存储(nonlocal storage)的引用方法,以及为了支持这种引用所需的实现结构,例如,活动记录(frame)和display表。

第13章  目标代码生成

本章和第11章很相似,不同之处是代码生成的目标是与VM相比更为低级的指令集。本章对于在代码生成过程中会遇到的问题进行了详细讨论,包括寄存器分配、临时变量管理、代码调度、指令选择和一些基本的窥孔优化技术。

第14章  程序优化

绝大多数编译器包括一些对它们生成的代码进行优化的能力。本章介绍在编译器中常用的程序优化的实用技术。本章会讲解高级的控制流分析结构和算法,另外还简要介绍了数据流分析(data flow analysis),并讨论了相对容易实现的一些基本优化技术。本章讲解这些优化技术的理论基础,并介绍了SSA形式的构造和使用。

致    谢

作者感谢如下人士在本书撰写过程中所提供的支持。我们感谢Pearson出版社的Matt Goldstein在本书修订过程中的耐心和支持。由于在本书撰写过程中造成的拖延,我们对Matt的前任深表歉意。我们也很感激Jeff Holcomb为我们提供了关于Pearson出版过程的技术指导。本教材在我们的审校编辑手中得到了很大的改进。Stephanie Moscola及时而专业地审校并修改了本书中的每一章。她进行了异常细致的工作,书中所有剩余的错误都是作者的错误。我们非常感激她锐利的眼睛和洞察力,以及提出的建议。我们感谢Will Benton对第12章和第13章的编辑,以及在12.5节中的部分撰写工作。我们感谢Aimee Beal被留在了Pearson来负责对本书的风格和一致性进行编辑修改。

我们非常感谢如下同事们付出了他们宝贵的时间审阅本书,并提出了非常宝贵的反馈:Ras Bodik(加州伯克利大学)、Scott Cannon(犹他州立大学)、Stephen Edwards(哥伦比亚大学)、Stephen Freund(威廉姆斯学院)、Jerzy Jaromczyk(肯塔基大学)、Hikyoo Koh(拉马尔大学)、Sam Midkiff(普渡大学)、Tim O'Neil(阿肯大学)、Kurt Stirewalt(密歇根州立大学)、Michelle Strout(科罗拉多州立大学)、Douglas Thain(圣母大学)、V. N. Venkatakrishnan(伊利诺伊大学芝加哥分校)、Elizabeth White(乔治梅森大学)、Sherry Yang(俄勒冈技术学院)和Qing Yi(得克萨斯大学圣安东尼奥分校)。

Charles Fischer:我对编译器着迷是从1965年在Robert Eddy先生的计算机实验课上开始的。虽然我们当时的计算机总共只有20KB的主存,而我们的编译器要使用打孔卡来作为它的中间媒介,但是编译的种子就是在那个时候种下的。

我的教育经历是从康奈尔大学开始的,在那里我学到了计算技术的深奥和严格。David Gries富有创意的编译器教材教给我很多知识,并引领我走上了我的职业道路。

威斯康辛大学的教员们,特别是Larry Landweber和Tad Pinkerton,允许我放开手脚建设编译课程和研究团队。教学计算中心的Tad、Larry Travis和Manley Draper给了我很多的时间和资源来学习编译的实践。威斯康辛大学的UW-Pascal编译器项目把我介绍给了许多优秀的学生,其中包括我的共同作者Richard LeBlanc。我们在实践中进行学习,而这也成为了我的教学理念。

在过去的许多年间,我的同事们,特别是Tom Reps、Susan Horwitz和Jim Larus,都很无私地让我分享了他们的智慧和经验,使我从中获益良多。在计算机体系结构方面,Jim Goodman、Guri Sohi、Mark Hill和David Wood向我传授了现代体系结构的点点滴滴。作为编译器的开发人员必须认真仔细地理解处理器,才能释放它的全部能力。

我最应该感激的是我的学生们,他们给我的课程带来了巨大的能力和热情。他们热切地接受了我所展示给他们的挑战。从扫描器到代码生成器开发一个完整的编译器,这是在一个学期内看起来肯定无法完成的任务,但是他们做到了,而且做得很好。此中的许多经验都渗入到了这本教材中。我确信教会新的一代人如何构造编译器是非常有意义的一项   工作。

Ron K. Cytron:我最初对程序设计语言和其编译器的兴趣以及之后的研究主要来自于在我的职业生涯中产生过重要作用的良师们。我们深切怀念的Ken Kennedy在Rice大学教过我的编译课。我现在所教的课程都是按照他的方式来设计的,特别是强调编程作业在帮助学生理解课程内容中的作用。Ken Kennedy是一位杰出的教育家,我只奢望能像他一样与学生进行交流。他还在位于纽约州Yorktown Heights的IBM T.J. Watson研究实验室雇我做了一个暑期的实习,主要工作是应用自动并行化的软件。在那个夏天,我的研究很自然地把我引到了Dave Kuck和他的学生在伊利诺伊大学的研究工作。

我依然认为Dave能让我成为他的研究生对我来说是非常幸运的。Dave Kuck在并行计算机体系结构,以及如何利用编译器来使如此高深的系统更加容易编程方面是一名先驱。我努力以他为榜样,学习他的努力工作、正直和坚持不懈,并把这些经验都传授给我的学生。我同样也经历了在一个团队中进行研究而带来的活跃和乐趣,并且试图在我的学生中间营造类似的氛围。

我作为本科生和研究生的经验把我引向了IBM Research的Fran Allen,我一直非常感激她允许我加入了她刚刚成立的PTRAN研究组。Fran在数据流分析、程序优化和自动并行化方面激励了几代人的研究工作。她对于许多重要问题及可能的解决方案拥有令人惊讶的直觉。在与同事们交谈中,我们一些最好的想法都来自于Fran,以及她为我们提供的建议、指导或批评。

我职业生涯中最好的几年是在向Fran和PTRAN同事们学习和与他们共事中度过的,他们是Michael Burke、Philippe Charles、Jong-Deok Choi、Jeanne Ferrante、Vivek Sarkar和David Shields。在IBM,我还非常高兴能从Barry Rosen、Mark Wegman和Kenny Zadeck那里学习并与他们共事。虽然我的朋友和同事们的印记在本书中随处可见,但所有的错误都是属于我的。

如果读者注意到在本书中频繁出现431这个数字的话,它是为了纪念所有在华盛顿大学跟我学习过编译的同学。从我的学生那里学到的和我教给他们的一样多,而我对本书所做的贡献主要都来自于我在教室和实验室里得到的经验。

最后,我要感谢我的妻子和孩子给我时间来准备这本书,他们在整个过程中展现了很好的耐心和理解。最后我要感谢Carole阿姨总是在询问这本书写得怎么样了。

Richard LeBlanc:在我获得物理学学士学位,并发现自己对计算机比物理问题更加感兴趣之后,我在1972年来到了麦迪逊,加入了威斯康辛大学成了一名计算机科学专业的博士生。两年后,一位刚刚从康奈尔拿到博士学位的年轻助理教授,Charles Fischer,加入了计算机科学系。他讲授的第一门课程是研究生的编译课(CS701)。我选了那门课,并且至今还记得当时令人难以忘怀的学习经历,而正是由于他是第一次讲授该课程才让人觉得更加难能可贵。我们显然彼此都很投缘,由此引向了一系列相当长时间的合作。

在Larry Travis的支持下,我从1974年夏天开始在教学计算中心工作,并因此在UW-Pascal项目在一年后开始的时候,我早已成了该组织的一员。这个项目不仅给我提供了机会来应用我在刚学过的两门课中所学到的知识,还交给我关于好的设计和设计评价的影响。在与我的两位研究生同学Steve Zeigler和Marty Honda的共事中我也受益良多,从他们身上我了解到作为一个有效的软件开发团队的一部分是多么有趣。我们都发现了使用Pascal工作的价值:Pascal是一个设计良好的语言,要求在编程中训练有素,并且我们使用的是自己开发的工具,因为我们在项目早期从Pascal的P-Compiler自举,得到了可以为Univac 1108生成本地代码的我们自己的编译器。

在完成了研究生学业之后,我接受了佐治亚理工学院的教职,因为我喜欢那里温暖的气候,以及由Phil Enslow领导的分布式计算研究项目,Phil在我职业生涯的早期提供了非常宝贵的指导。我立即得到了讲授一门编译器课程的机会,并且试图模仿在威斯康辛学习的CS 701课程,因为我强烈相信Charles使用过的以项目为基础的教学方式。我迅速地意识到要学生在10周的小学期内开发一个完整的编译器是太大挑战。因此我开始使用另外的方法:给他们一个非常小的语言的可用编译器,然后课程项目是围绕对这个编译器的所有模块进行扩展来编译更加复杂的语言。在我的10周课程中使用的基础编译器就成了Fischer-LeBlanc教材中所带的辅助支持材料之一。

我的职业规划使得我参与软件工程和教学工作相比编译器研究要更多。当我回顾在威斯康辛大学的早期编译器经验,我清晰地看到我对这两个领域都很感兴趣。Charles和我最早决定开始编写第一版的《编译器构造》是基于我们相信可以帮助其他教师,通过基于项目的编译器课程,能为他们的学生提供更好的教学经历。在我们的编辑Alan Apt,以及许多审阅者的宝贵帮助下,我相信我们已经取得了成功。许多同事都向我提到他们对于我们最初版本的教材以及《编译器构造:C语言描述》的热情。他们的支持是一种巨大的奖励,鼓励我们最终完成了这本新版的教材。特别要感谢的是Joe Bergin,他除了口头支持之外,还把我们早期的软件工具翻译成了新的编程语言,并且允许我们把他的版本提供给其他教师使用。

在佐治亚理工学院的岁月给我提供了很好的机会来发展我对计算机教育的兴趣。在我职业生涯的早期,我很有幸成为先是由Ray Miller,然后是Pete Jensen所领导的团队的一员。从1990年开始,我非常高兴能与Peter Freeman一起工作,创立并发展了计算学院。除了在佐治亚理工学院的时候Peter对我的多方指导之外,他还鼓励我参与了ACM Education Board与教育相关的工作,这些工作在过去12年中极大地丰富了我的职业生涯。

最后,我要感谢我的家人,包括刚出生的孙女,在写作本书的漫长过程中一直陪伴我。

献    词

CNF:献给Lisa

  怀念属于伟大一代的Stanley J. Winiasz

RKC:献给Betsy、Jessica、Malanie和Jacob

  怀念Ken Kennedy

RJL:献给Lanie、Aidan、Maria和Evolette

缩  略  语

AST (abstract syntax tree) 抽象语法树

BEG (back-end generator) 后端生成器

BNF (Backus-Naur form)  Backus-Naur范式

BURS (bottom-up rewriting systems) 自底向上的重写系统

CFG (context-free grammar) 上下文无关文法

CFL (context-free language) 上下文无关语言

CFSM (characteristic finite-state machine) 特征有限状态机

CIL (Common Intermediate Language)  通用中间语言

CLR (Common Language Runtime) 通用语言运行库

DAG (directed acyclic graph)  有向无环图

DBL (dangling bracket language)  悬空的括号语言

DFA (deterministic finite automaton) 确定性的有限自动机

DFST (depth-first spanning tree) 深度优先生成树

DIANA (Descriptive Intermediate Attributed Notation for Ada)  Ada语言的描述性中间属性记法

EOF (end-of-file) 文件结尾符

FA (finite automaton) 有限自动机

GCC (GNU Compiler Collection) GNU编译工具集

GNF (Greibach normal form)  格雷巴赫范式

IDE (integrated development environment) 集成开发环境

IL(intermediate language) 中间语言

IR(intermediate representation) 中间表示

JDK (Java Development Kit)  Java开发包

JIT (just-in-time) 即时(编译)

JVM (Java Virtual Machine)  Java虚拟机

L-value (left value)  左值

LHS (left-hand side)  左部

MFP (maximum fixed point)  最大不动点

MOP (meet over all paths)  所有路径的交

MOSS (Measure Of Software Similarity) 软件相似度度量

MSIL (Microsoft Intermediate Language) 微软中间语言

NFA (nondeterministic finite automaton) 非确定性的有限自动机

NUMA (non-uniform memory access) 非一致性内存访问

R-value (right value) 右值

RHS (right-hand side) 右部

RISC (reduced instruction set computer) 精简指令集计算机

RPN (reverse Polish notation) 逆波兰表示法

RTL (register-transfer level) 寄存器传输级

SSA (static single assignment) 静态单赋值

TOS (top-of-stack) 栈顶

VLSI (very large scale integration) 超大规模集成电路

VM (virtual machine) 虚拟机

WPO (whole-program optimization) 全程序优化