编译器编程:最基本的成分是什么?

时间:2009-02-17 22:31:25

标签: c++ c compiler-construction low-level

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

我想写一小段软件(用C / C ++),它符合以下标准:

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

语言功能:

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

有谁能告诉我怎么开始?我不知道编译器包含哪些部分(至少在某种意义上我不能直接启动)以及如何对它们进行编程。谢谢你的想法。

8 个答案:

答案 0 :(得分:7)

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

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

如果我是你,我可以从汇编程序开始,并在其上构建部分。最简单的“编译器”可能只使用一些非常简单的语句来使用语言:

print "hello"
a = 5
print a

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

祝你好运!

答案 1 :(得分:5)

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

一旦做出决定,就会有一些常见的步骤

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

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

  3. 解析下一步是创建一个与您的令牌列表匹配的语法。您可以使用例如定义语法无上下文的语法。可以使用这些语法之一来提供许多工具,并为您创建解析器。通常,解析的标记被组织成一个解析树。解析树是您的语法表示为可以移动的数据结构。

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

  5. 维基百科非常适合学习更多内容,您可能想要开始here

    关于现实世界的阅读材料,我建议由David A Watt& Sons撰写的“JAVA编程语言处理器”。 Deryck F Brown。我在编译器课程中使用了这本书,通过实例学习在这个领域很有用。

答案 2 :(得分:4)

这些是绝对必要的部分:

  • 扫描程序:这会将输入文件分解为标记
  • Parser:这是从扫描程序识别的标记构造一个抽象语法树(AST)。
  • 代码生成:这将生成AST的输出。

您可能也想要:

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

编辑:你已经设计了这门语言吗?如果没有,你也会想要研究语言设计。

答案 3 :(得分:2)

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

虽然本书使用Pascal作为实现和目标语言,但所提供的课程和技术同样适用于所有其他语言。

答案 4 :(得分:2)

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

整体编译教程:让Jack Crenshaw编写一个编译器(http://compilers.iecc.com/crenshaw/)这很罗嗦,但我喜欢它。

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

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

我正在尝试写一个LISP,所以我正在使用Lisp 1.5 Manual。您可能希望获得您正在编写的任何语言的语言规范。

就1-2KLOC而言,假设您使用的是高级语言(如Py或Rb),如果您不是太野心勃勃,那么您应该接近。

答案 7 :(得分:0)

我始终建议flexbison作为初学者进行此类工作。您可以随时了解编写自己的扫描仪和解析器的细节,尽管它们可能会增加代码大小,至少它们将通过工具为您生成。 :)