在我的高级编译器构造课程的实际应用项目中,我与一个四人团队合作,我们的主要任务是利用 Java 编程语言设计和构建一个定制编译器。我们开发的编译器旨在将用 Xi 编写的源代码作为输入,Xi 是一种在命令式、静态类型和过程范式上类似于 C 的编程语言。我们的编译器最终生成的是符合 x86 架构规范的可执行文件。
整个编译器的设计和开发都是从头开始的,包含了一系列基本组件。这些基本单元,包括词法分析器(或称为 lexer)、语法分析器(或称为 parser)、中间表示(IR)生成器和代码生成器,都是从零开始编写的。每个组成部分在从源代码到最终可执行文件的转换过程中都起着关键作用。
翻译过程的第一部分是词法分析器,使用 Construction of Useful Parsers (CUP) 生成器应用于自定义语法文件。词法分析器在编译器设计中的作用是分析来自源代码的字符流,并根据给定的语法规则将其转换为有意义的标记(tokens)。这些标记是语义单元,如标识符、关键字、操作符和其他语法元素。
成功的词法分析后,生成的标记被传递给语法分析器,这是翻译流水线的第二步。在这里,语法分析器负责分析由词法分析器提供的标记流,以确保其符合指定的语法。这种语法检查涉及构建抽象语法树(AST),该树封装了各种标记之间的层次关系。然后将树转换为中间表示(IR),一种较低级的平台无关的数据格式。
生成的 IR 使用我们自定义的数据结构设计,提供了一种更易于管理的格式,用于优化和生成目标代码。在这个阶段部署了一种重要的优化技术,即常量折叠。该方法侧重于在编译时识别和计算代码中恒定的表达式,从而消除了在运行时对其不必要的计算,从而提高了执行效率。
最后,IR 被传递给翻译过程的最后一个组件,代码生成器。该模块解释优化后的 IR 以输出符合目标机器架构(在本例中为 x86)的代码。代码生成器还运行额外的优化技术,以进一步提高代码的性能和效率。因此,这个复杂过程的最终产品是一个可执行文件,它准确反映了最初的 Xi 源代码,同时遵循高级编译器构造的效率和优化原则。
遗憾的是,由于康奈尔关于学术诚信的规定,源代码不能向公众公开。