6

我有兴趣编写一个非常简约的编译器。

我想编写一个满足以下条件的小软件(在 C/C++ 中):

  • 以 ELF 格式输出 (*nix)
  • 输入是单个文本文件
  • 类 C 语法和句法
  • 没有链接器
  • 没有预处理器
  • 非常小(最多 1-2 KLOC)

语言特点:

  • 本机数据类型:char、int 和 floats
  • 数组(适用于所有本机数据类型)
  • 变量
  • 控制结构(if-else)
  • 职能
  • 循环(会很好)
  • 简单代数(div、add、sub、mul、布尔表达式、位移等)
  • 内联汇编(用于系统调用)

谁能告诉我如何开始?我不知道编译器由哪些部分组成(至少在我可以立即开始的意义上)以及如何对它们进行编程。谢谢你的想法。

4

8 回答 8

7

对于您希望完成的所有工作,最具挑战性的要求可能是“非常小(最多 1-2 KLOC)”。我认为仅您的第一个要求(生成 ELF 输出)本身就可能需要超过一千行代码。

至少在开始时,简化问题的一种方法是生成汇编语言文本中的代码,然后将其输入现有的汇编程序(nasm将是一个不错的选择)。汇编器将负责生成实际的机器代码,以及构建实际可运行的可执行文件所需的所有 ELF 特定代码。然后你的工作就变成了语言解析和汇编代码生成。当您的项目成熟到要删除对汇编程序的依赖时,您可以自己重写这部分并随时插入。

如果我是你,我可能会从一个汇编器开始,然后在它之上构建部件。最简单的“编译器”可能会采用一种只有一些非常简单的可能语句的语言:

print "hello"
a = 5
print a

并将其翻译成汇编语言。一旦你开始工作,你就可以构建一个词法分析器和解析器以及抽象语法树和代码生成器,这是现代块结构语言所需的大部分部分。

祝你好运!

于 2009-02-18T00:28:28.957 回答
5

首先,您需要决定是要制作编译器还是解释器。编译器将您的代码翻译成可以直接在硬件上、在解释器中运行的东西,或者被编译成另一种语言,然后以某种方式被解释。两种类型的语言都是图灵完备的,因此它们具有相同的表达能力。我建议您创建一个编译器,将您的代码编译为 .net 或 Java 字节码,因为它为您提供了一个非常优化的解释器来运行以及许多标准库。

一旦你做出决定,有一些常见的步骤可以遵循

  1. 语言定义首先,您必须定义您的语言在语法上的外观。

  2. Lexer第二步是创建代码的关键字,称为标记。在这里,我们谈论的是非常基本的元素,例如数字、加法符号和字符串。

  3. 解析下一步是创建一个与您的标记列表匹配的语法。您可以使用例如上下文无关语法来定义您的语法。许多工具可以使用其中一种语法并为您创建解析器。通常,已解析的标记被组织成一棵解析树。解析树是将语法表示为可以在其中移动的数据结构。

  4. 编译或解释最后一步是在分析树上运行一些逻辑。制作自己的解释器的一种简单方法是创建一些与树中的每个节点类型相关联的逻辑,然后自下而上或自上而下地遍历树。如果你想编译成另一种语言,你可以在节点中插入如何翻译代码的逻辑。

维基百科非常适合了解更多信息,您可能想从这里开始。

关于现实世界的阅读材料,我建议 David A Watt 和 Deryck F Brown 撰写的“Java 编程语言处理器”。我在我的编译器课程中使用了那本书,并且通过示例学习在这个领域非常棒。

于 2009-02-17T23:00:28.497 回答
4

这些是绝对必要的部分:

  • 扫描仪:这会将输入文件分解为标记
  • 解析器:这会根据扫描仪识别的标记构造抽象语法树 (AST)。
  • 代码生成:这会产生来自 AST 的输出。

您可能还想要:

  • 错误处理:这告诉解析器如果遇到意外令牌该怎么办
  • 优化:这将使编译器能够生成更高效的机器代码

编辑:你已经设计了语言吗?如果没有,您也需要研究语言设计。

于 2009-02-17T22:43:03.797 回答
2

最重要的是一本关于编译器编写的书。很多人会告诉你阅读 Aho 等人的“Dragon Book”,但我读过的关于编译器的最好的书是“Brinch Hansen on Pascal Compilers”。我怀疑它已经绝版了(亚马逊是你的朋友),但它会带你完成使用递归下降设计和编写编译器的所有步骤,这是编译器新手最容易理解的方法。

尽管本书使用 Pascal 作为实现和目标语言,但所介绍的课程和技术同样适用于所有其他语言。

于 2009-02-17T22:56:50.627 回答
2

我不知道你希望从中得到什么,但如果它正在学习,并且查看现有代码对你有用,那么总会有tcc

于 2009-02-17T23:00:19.777 回答
1

这些示例都在 Perl 中,但是Exploring Programming Language Architecture in Perl是一本好书(而且免费)。

于 2009-02-17T23:02:54.747 回答
1

恕我直言,一组非常好的免费参考资料是:

总体编译器教程:Jack Crenshaw 的 Let's Build a Compiler ( http://compilers.iecc.com/crenshaw/ ) 有点啰嗦,但我喜欢。

汇编程序:NASM ( nasm.us ) 适用于 Linux 和 Windows/DOS,最重要的是大量文档和示例/教程。(FASM也不错,但文档/教程较少)

其他来源 PC 组装书 ( http://www.drpaulcarter.com/pcasm/index.php )

我正在尝试编写 LISP,所以我使用的是Lisp 1.5 Manual。您可能想要获取您正在编写的任何语言的语言规范。

至于 1-2KLOC,假设您使用高级语言(如 Py 或 Rb),如果您不太雄心勃勃,您应该接近。

于 2009-02-24T01:50:58.633 回答
0

作为初学者,我总是推荐flexbison来完成这种工作。您以后可以随时了解编写自己的扫描仪和解析器的细节,尽管它们可能会增加代码大小,至少它们将由工具为您生成。:)

于 2009-02-20T01:18:19.943 回答