一遍和多遍编译器之间的区别?

BOT*_*Jr. 9 compiler-construction

我已经看过很多关于一次传递多次传递编译器的帖子,但我似乎没有明白这一点.

  • 什么是通过 编译器?

  • 什么是多通道编译器?

  • 它们之间的主要区别是什么?

  • 任何人都可以用非常简单的语言提供它们之间的区别吗?

Ira*_*ter 13

多遍这一术语的起源来自计算机内存少得多的时代.编译器需要大量内存,而在小型内存机器中,这很难管理.

所以最初的想法是编译器在多次传递中运行.第一遍读取源代码,并完成基本任务,如语法检查,可能构建符号表,然后将其结果写入磁盘文件以进行第二次传递.每个连续的传递N将读取前一个传递的结果,并改变程序表示以进一步向机器代码移动,并写出其结果以传递N + 1来读取.重复此过程,直到最后一遍产生最终代码.许多编译器可以获得一些("多")通道; 有很多知名的编译器,在很旧的机器上建立了几十个通道.

(这个相同的概念适用于所谓的"两遍汇编程序":第一遍读取汇编程序源代码,语法检查,确定应该使用哪些位置值作为标签符号;第二遍使用分配的符号位置的知识生成目标代码在第一次通过).

内存现在更大了,将每个非常大的程序的源代码读入内存非常实用,让编译器在单个进程的内存中完成所有工作,并编写目标代码.你仍然在链接器的概念中看到一些类比的残余; 它们将多个对象模块("第一遍")粘合到一个二进制文件中.

如果你在内部看编译器,它们会分阶段运行.典型的阶段可能是:

*  Parse and syntax check
*  Build symbol tables
*  Perform semantic sanity check
*  Determine control flow
*  Determine data flow
*  Generate some "intermediate" language (representing abstract instructions)
*  Optimize the intermediate language
*  Generate machine code from the optimized language
Run Code Online (Sandbox Code Playgroud)

特定编译器对各阶段的作用因编译器而异.这些步骤中的每一步都使程序表示更接近最终机器代码.N-pass编译器会将这些步骤中的一个或多个捆绑到一个传递中.

回到现在,我们有很多记忆; 不需要现代编译器将中间结果写入磁盘文件,因此所有这些阶段都发生在单个进程的内存中.您,编译器用户,看不到它们.因此,您可以将原始意义上的现代编译器称为"一次通过".由于现在没有人关心,这句话简直就是废弃了.

无论如何,编译器内部通常仍然是多阶段的 .(有些编译器在单个阶段执行所有这些步骤;通常,他们不能进行大量的优化).


sep*_*p2k 7

多传递编译器是将编译分成多个传递的编译器,其中每个传递将继续前一传递的结果.这样的传递可以包括解析,类型检查,中间代码生成,各种优化传递以及最终代码生成.因此,例如,解析器可能会创建一个解析树,然后类型检查器将检查类型错误,中间代码生成器可以转换为某种形式的中间代码.然后,优化过程将各自获取当前中间代码并将其转换为更优化的形式.最后,代码生成过程将采用优化的中间代码并从中生成目标代码.

在单通道编译器中,所有步骤都在一次通过中发生.因此,它会读取一些源代码,对其进行分析,对其进行检查,对其进行优化并为其生成代码,然后再转到下一段代码.

单通道编译器消耗更少的内存(因为它们不会将整个AST和/或中间代码保存在内存中)并且通常运行得更快.

有些语言,如C语言,可以在一次通过中进行编译,但其他语言则不是.例如,C中的函数需要在第一次使用之前声明,因此编译器在读取函数调用之前已经看到了函数的类型签名.然后,它可以使用该信息进行类型检查.在更现代的语言中,例如Java或C#,可以在定义之前调用函数(并且不存在前向声明).这样的语言不能在一次传递中编译,因为类型检查器在遇到函数调用时可能对函数的签名一无所知,因此在没有首先处理整个文件的情况下就无法对程序进行类型检查.

此外,多传递编译器可以使用更多种类的优化,因此即使对于可以一次编译的语言,现代编译器通常也使用多次传递.

  • @ sepp2k参见Aho,Lam,Sethi和Ullman:编译器:原理,技术和工具,第2版.Addison-Wesley 2007.这是关于编译器编写的标准教科书.在第4-11页,他们讨论了编译器*阶段*,例如词法分析,语法分析和代码优化.在第11页,他们说:"阶段的讨论涉及编译器的逻辑组织.在一个实现中,来自几个阶段的活动可以被分组为一个*pass*,它读取输入文件并写入输出文件." 这符合Ira Baxter的回答. (5认同)
  • 哦,你怎么定义一个通行证呢?它必须是阶段的组合?那怎么可以用作同义词呢? (2认同)