Compiler construction 单过程和多过程编译器之间的区别?

Compiler construction 单过程和多过程编译器之间的区别?,compiler-construction,Compiler Construction,我看过很多关于一次编译和多次编译的帖子,但我似乎没有抓住要点 什么是一次编译 什么是多通道编译器 它们之间的主要区别是什么 有人能用一种非常简单的语言来说明它们之间的区别吗 术语“多重传递”的起源来自计算机内存大大减少的时代。编译器需要大量内存,而在小型内存机器中,这很难管理 因此,最初的想法是在多个过程中运行编译器。第一个过程读取源代码,并执行基本任务,如语法检查,可能构建符号表,然后将结果写入磁盘文件以进行第二个过程。每个连续的过程N将读取前一个过程的结果,并更改程序表示以使其越来越接近机

我看过很多关于一次编译多次编译的帖子,但我似乎没有抓住要点

  • 什么是一次编译

  • 什么是多通道编译器

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

  • 有人能用一种非常简单的语言来说明它们之间的区别吗

术语“多重传递”的起源来自计算机内存大大减少的时代。编译器需要大量内存,而在小型内存机器中,这很难管理

因此,最初的想法是在多个过程中运行编译器。第一个过程读取源代码,并执行基本任务,如语法检查,可能构建符号表,然后将结果写入磁盘文件以进行第二个过程。每个连续的过程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
一个特定的编译器在各个阶段所做的工作因编译器而异。这些步骤中的每一步都使程序表示更接近最终机器代码。N-pass编译器会将这些步骤中的一个或多个捆绑到单个过程中

回到现在,我们有很多记忆;现代编译器不需要将中间结果写入磁盘文件,因此所有这些阶段都发生在单个进程的内存中。您,编译器用户,看不到它们。因此,你可以将现代编译器称为“一次通过”这个词的原始含义。由于现在没人在意,这个短语就被废弃了


无论如何,编译器在内部通常仍然是多阶段的。(有些编译器在一个阶段内完成所有这些步骤;通常情况下,它们无法进行大量的优化)。

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

在单过程编译器中,所有步骤都发生在一个过程中。因此,它读取一些源代码,对其进行分析、类型检查、优化并为其生成代码,然后才转到下一位代码

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

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

此外,多过程编译器可以使用更多种类的优化,因此即使对于可以在一个过程中编译的语言,现代编译器也通常使用多个过程

编译器中的过程只不过是贯穿整个程序 从上到下一次

。通常一个过程包括几个阶段。通常一个过程就足以完成词法和语法分析。也就是说,通过对整个程序进行一次检查,我们可以检查语句的语法是否正确。然后语法分析的输出是一个抽象语法树,它只不过是以树的形式出现的源代码(浓缩)。语义分析器必须通过AST来完成它的工作,并在那里有效地再次遍历整个程序。 也就是说,要完成语义分析,需要两个过程(如果需要显式AST)

  • 单通道编译器是只通过每个编译单元的源代码一次的编译器。多程编译器是一种编译器,它多次处理程序的源代码或抽象语法树

  • 单通道编译器比多通道编译器更快

  • 一传