替代的编译方法?

时间:2015-12-31 21:21:00

标签: compiler-construction

我已经学习了几年的编译器(以及编程语言设计等相关主题),并且已经了解到大多数编译器都会遵循以下基本设计:

  1. 词汇分析
  2. 语法/语义分析
  3. AST Generation
  4. 代码生成
  5. 当然,您如何遵循和实施这些步骤有很多自由,但在某种程度上,这是编译器的基本方案。我的问题是,特别是有这么多新的函数式编程语言和方法,还有其他编译源代码的方法吗?理论上起作用的方法以及列出的方法,但遵循完全不同的方案。除了答案,我还会欣赏文章,书籍等,以获取更多相关信息。谢谢,祝新年快乐!

2 个答案:

答案 0 :(得分:1)

现实世界优化编译器的大部分工作发生在步骤3(AST生成)和4(代码发射)。对于海湾合作委员会来说,它覆盖了超过四分之四的1500万行。

Ocaml编译器在这两个步骤之间也有几个内部转换更改。值得注意的是,类型推断步骤正在将一些无类型AST转换为类型化AST。阅读A-normal forms& Continuation Passing Style

事实上,编译器正在转换许多内部表示,直到最终发出的输出(例如汇编代码)。

看看我的参考文献&在http://gcc-melt.org/docum.html上滑动更多内容。

如果你知道一些Scheme或Lisp方言,请阅读Queinnec的Lisp In Small Pieces书,它探讨了实现Lisp解释器的许多方法。编译器。

另见J.Pitrat的blog:他的CAIA系统有几种内部表征的转换,从更多的声明形式到更多的程序形式。

答案 1 :(得分:0)

为什么要对这些步骤进行分类

最后,我们将这些任务划分为多个类别的主要原因是为了更容易理解编译器的复杂性。这些任务对于任何语言处理(即使对于非编程语言)都是必需的,尽管有时它们是如此琐碎,以至于我们往往会忽略它们(例如,某些脚本语言一旦具有可执行字节,就不会真正“生成代码” -code,它们只是解释它,但您仍然可以说这些编程语言“编译”为字节码。Shell语言通常实际上并没有明确的“ AST”。)

我们可以编写一个以不同方式执行这些步骤的编译器吗

语言/编译器的编写方式可能永远不会明确地执行这些步骤中的一个(或多个),但最终它仍然会以一种或另一种方式来完成所有这些步骤。一个典型的例子是机器代码。 CPU仍然必须对其进行语法分析,现代的CPU甚至可以通过分支预测和微代码执行“代码生成/优化”步骤。 “ lexing”等效于在指令表中查找一个字节,“ AST”也许不过是一个或两个用于记住指令操作数的内部寄存器。

我们为什么不以不同的方式编写编译器

在代码中分离这些步骤还有其他好处,因此我们可以并行运行它们,或者至少可以按需运行。

对于大多数现代编程语言,词法分析比解析/ AST生成花费的时间(可能令人惊讶)要多得多,这是因为数据量很大(与数十万个令牌相比,十亿个字符很容易),但此后不断折叠,类型检查,程序集优化和寄存器分配再次占据了编译器的执行时间。

通过分开这些步骤,我们可以优化整个过程,例如通过对每个线程进行词法分析,解析和编译一个函数。实际上,有了AST之后,一些代码生成和优化可以再次并行运行。因此,您的“代码生成”步骤可以再次有意义地分为许多不同的较小的优化和生成步骤,这使我们可以更详细地考虑编译器。然后,我们也许可以并行运行其中一些较小的步骤。 JIT编译器非常擅长于此,它使它们比典型的编译器快得多。但是最后,他们仍然必须执行您不断听到的所有基本步骤。