目录
前言
语言的基础是一组符号和一组规则,根据规则由符号构成的符号串的总体就是语言;程序设计语言就是编写计算机程序的语言。但是,在一个程序可以运行之前,它需要被翻译成一种能够被计算机执行的形式。因此,引论篇从高级程序设计语言出发,介绍编译与解释两种翻译方式;然后概述一个编译过程具有的典型逻辑阶段,介绍一个典型编译程序的结构;最后简单介绍与编译程序有关的概念,包括前端与后端、趟、自编译、自展以及移植。
编译有两种方式:一种是编译方式,一种是解释方式
一、什么是编译程序
将一份源程序从头至尾翻译成某台计算机上的机器语言,让机器接受,然后执行之,并允许重复执行若干次
编译程序是一种将高级语言代码翻译成机器语言的程序。编译程序可以将高级语言的程序源代码转换为目标代码,以便在计算机上直接执行。编译程序通常由编译器实现,编译器是一种将高级语言代码转换为目标代码的软件工具,通常将源代码转换为机器语言的目标代码,以便于计算机直接执行。 编译程序通常分为两个阶段:编译和链接。编译阶段将源代码转换为汇编代码或二进制机器代码,这个阶段通常包括词法分析、语法分析、语义分析和代码生成等过程。链接阶段将生成的目标代码与外部库、环境等组件进行连接,以生成最终的可执行代码。 使用编译程序可以实现高级语言的跨平台编程,因为编译程序会根据目标平台的硬件和软件环境生成正确的机器语言代码。在开发复杂的软件系统时,使用编译程序可以提高代码的安全性、可读性和可维护性。
常见的使用编译方式的高级语言有:
1. C:C是一种广泛使用的系统编程语言,由于使用编译器编译执行,因此具有高效和可移植等特点,被广泛应用于操作系统、设备驱动和底层程序等开发领域。
2. C++:C++是一种基于C语言的编程语言,由于使用编译器编译执行,因此既具有C语言的高效性和可移植性,也具有面向对象、泛型编程和模板等高级特性,被广泛应用于开发复杂的系统和应用程序。
3. Java:Java是一种跨平台的高级语言,由于使用编译器编译执行成平台无关的字节码,因此具有良好的跨平台性,同时也具有面向对象、垃圾回收和多线程等高级特性,被广泛应用于Web应用程序、移动应用程序和企业级应用程序等开发领域。
4. Pascal:Pascal是一种简单、清晰和易学的编程语言,由于使用编译器编译执行,因此具有高效和可读性等特点,被广泛应用于学术和科研领域,如计算机程序设计、算法和数据结构等。
5. Fortran:Fortran是一种广泛应用于科学计算和数值分析的编程语言,由于使用编译器编译执行,因此具有高效和优化计算的特点,在物理学、天文学、化学、工程和金融等领域具有广泛的应用。 使用编译方式的高级语言通常具有高效、可移植和可控的优点,而也存在一些缺点,如开发复杂度高、调试困难等问题,需要根据具体的应用场景进行选择。
1)机器语言Machine Language
一般来说,计算机可以直接执行的代码形式的指令系统称为机器语言
机器语言是一种计算机可读的二进制编码,它是计算机硬件直接能够理解和执行的指令代码,也是计算机程序最基础的形式。机器语言编码通常是一组0和1的位序列,每个二进制编码对应着特定的计算机指令和操作,这种指令和操作由计算机中的硬件进行解释和执行。机器语言是二进制代码的形式,与高级编程语言相比,它的表达能力比较有限,但是具有最高的执行效率,常常用于编写底层操作系统或硬件设备的驱动程序等需要高效执行的任务。
小tips:
DJS-21计算机是1980年代末期中国科技企业为国防部设计和制造的一款16位微机。它基于Intel 8086微处理器,采用汇编语言写成。DJS-21计算机集合了当时国内研究所和大学的计算机技术精华,具有较高的性能和可靠性,曾在军队、国防科技领域等多个领域得到广泛应用。DJS-21计算机的开发和制造代表了当时中国自主研发计算机的一定水平,也为中国计算机技术的进步和发展奠定了基础。
DJS-21计算机已经距离它的诞生30多年了,目前已经退出了市场,基本上已经不再被使用。虽然DJS-21计算机在当时是国内的顶尖技术,但是现在已经远远不能满足现代计算机处理的高效率和高容量的需求。现代计算机硬件和软件方面都有了很大的发展,使用带来了更高的处理能力、更好的计算体验和更多的功能。因此,DJS-21计算机已经成为了历史的一页,而现代计算机已经成为了国内和全球用户的主要选择。
2)汇编语言Assembly Language
汇编语言就是计算机符号形式的指令系统
如对应取、除、减、送则分别采用符号:CLA/DIV/SUB/STO
CLA/DIV/SUB/STO是汇编语言的指令操作。具体来说: - CLA代表Clear Accumulator,用于将累加器的值清零。 - DIV代表Divide,用于在累加器中将一组数值相除。 - SUB代表Subtract,用于在累加器中将一组数值相减。 - STO代表Store,用于将数据存储到指定的存储器地址中。 这些指令操作通常是面向特定的硬件架构的汇编语言,旨在通过直接操作硬件来实现特定的功能。这些指令操作通常对应于特定的机器指令,该类机器指令通常由特定的微处理器支持,这种微处理器可能针对特定应用程序或特定型号的计算机开发。
3)高级语言
高级语言是相对于机器语言和汇编语言而言的,它是指用于编写计算机程序的一种人类可读的程序设计语言,这种语言的特点是更接近自然语言,更容易理解和学习,编写出的程序通常具有更高的可读性和可维护性,同时也提高了编程的效率。 高级语言可以通过编译器或解释器将其源代码转换为机器语言或汇编语言,以便计算机可以直接执行。常见的高级语言包括C、C++、Java、Python、Ruby、PHP、JavaScript等。 高级语言通常具有丰富的语法和内置函数库,可以提供各种各样的数据结构和算法,同时还可以通过面向对象编程、函数式编程等方式实现程序的复杂性和抽象性。高级语言的程序通常更加易于移植和扩展,也更容易进行团队协作和软件工程管理。
4)计算机实现程序设计语言的方法
二、解释程序
解释程序是一种将高级语言代码逐行解释执行的程序。解释程序通常由解释器实现,解释器是一种可以解释和执行高级语言程序的软件工具。与编译程序不同,解释器不需要将源代码翻译成机器语言的目标代码,而是在运行时逐行解释执行源代码。 解释程序通常包括解释器和虚拟机两部分。解释器将源代码解释成中间代码,虚拟机再将中间代码转换成可执行代码。解释程序通常不需要进行编译和链接的过程,因此可以在不同的平台上运行,也可以通过修改源代码直接进行调试。 使用解释程序可以方便地进行代码调试和修改,因为每一行代码都可以逐行执行和检查,同时也避免了编译程序中因为编译错误等原因无法运行程序的问题。解释程序也可以实现语言的动态性,例如交互式编程、动态类型等功能。 但解释程序的执行速度通常比编译程序慢,因为每行代码都需要经过解释器的解释和虚拟机的转换。对于复杂的程序,解释程序的性能可能无法满足需求,这时候一般会选择使用编译程序进行优化。
常见的使用解释方式的高级语言有:
1. Python:Python是一种流行的脚本语言,由于使用解释器执行,因此在运行时可以动态修改代码,同时也具有交互式编程和动态类型等特点。
2. Ruby:Ruby是一种动态的、面向对象的脚本语言,由于使用解释器执行,可以快速开发和测试程序,同时也具有深厚的开发社区和丰富的库和框架。
3. JavaScript:JavaScript是一种广泛应用于Web前端开发的脚本语言,由于使用解释器执行,可以在浏览器中直接执行代码,并实现动态加载和修改页面内容的功能。
4. PHP:PHP是一种广泛用于Web开发的脚本语言,由于使用解释器执行,可以在服务器上直接执行程序,并实现动态生成HTML页面的功能。
5. Perl:Perl是一种流行的脚本语言,由于使用解释器执行,可以快速开发和处理文本数据,同时也具有正则表达式和模块化等强大的功能。 使用解释方式的高级语言通常具有快速开发和动态性等优点,而也存在性能较低和安全性等问题,需要根据具体的应用场景进行选择。
三、编译过程和编译程序结构
1)词法分析
主要任务:从左到右扫描源程序,识别单词及其有关属性,并转换成属性字。
词法分析是编译器的第一个阶段,也称为扫描(Scanning)或者词法扫描(Lexical Scanning),其目的是将输入的源代码分解为词法单元(Token)序列,其中每个词法单元表示语言中的一个原子性元素,如标识符、关键字、运算符、常量等。 词法分析由词法分析器(Lexer)实现,它通过自动机、正则表达式或手写代码等方式,从输入的字符流中提取出有意义的词法单元,并生成对应的Token序列,以便后续阶段对代码进行语法分析、语义分析和代码优化等处理。
以C语言为例,源代码中的字符流将被词法分析器分解为不同的词法单元,例如:
int main() {
int a = 1 + 2;
return a;
}
```
将被分解为以下词法单元序列:
```
1. Token{Type: KEYWORD, Value: int}
2. Token{Type: IDENTIFIER, Value: main}
3. Token{Type: SYMBOL, Value: (}
4. Token{Type: SYMBOL, Value: )}
5. Token{Type: SYMBOL, Value: { }
6. Token{Type: KEYWORD, Value: int}
7. Token{Type: IDENTIFIER, Value: a}
8. Token{Type: SYMBOL, Value: =}
9. Token{Type: INTEGER_CONST, Value: 1}
10. Token{Type: SYMBOL, Value: +}
11. Token{Type: INTEGER_CONST, Value: 2}
12. Token{Type: SYMBOL, Value: ;}
13. Token{Type: KEYWORD, Value: return}
14. Token{Type: IDENTIFIER, Value: a}
15. Token{Type: SYMBOL, Value: ;}
16. Token{Type: SYMBOL, Value: } }
```
1. Token{Type: KEYWORD, Value: int}:关键字,表示变量类型int。
2. Token{Type: IDENTIFIER, Value: main}:标识符,表示程序中的主函数名称。
3. Token{Type: SYMBOL, Value: (}:符号,表示函数参数列表的开始。
4. Token{Type: SYMBOL, Value: )}:符号,表示函数参数列表的结束。
5. Token{Type: SYMBOL, Value: { }:符号,表示代码块的开始。
6. Token{Type: KEYWORD, Value: int}:关键字,表示变量类型int。
7. Token{Type: IDENTIFIER, Value: a}:标识符,表示变量名为a。
8. Token{Type: SYMBOL, Value: =}:符号,表示赋值运算符。
9. Token{Type: INTEGER_CONST, Value: 1}:整数常量,表示变量a的初始值为1。
10. Token{Type: SYMBOL, Value: +}:符号,表示加法运算符。
11. Token{Type: INTEGER_CONST, Value: 2}:整数常量,表示加数为2。
12. Token{Type: SYMBOL, Value: ;}:符号,表示语句结束。
13. Token{Type: KEYWORD, Value: return}:关键字,表示返回语句。
14. Token{Type: IDENTIFIER, Value: a}:标识符,表示返回值为变量a。
15. Token{Type: SYMBOL, Value: ;}:符号,表示语句结束。
16. Token{Type: SYMBOL, Value: } }:符号,表示代码块的结束。
2)语法分析
主要任务:分析源程序的结构,判别它是否为相应程序设计语言中的一个合法程序
语法分析是编译器的第二个阶段,也称作解析(Parsing),其主要任务是检查源代码是否符合语法规范,并将其转换为中间代码表示形式,以方便后续的分析和代码生成。 语法分析的过程通常涉及到文法定义、语法树构造和编译器生成等内容,其核心是将源代码转换为抽象语法树(Abstract Syntax Tree,AST)的形式,即将代码转换为以语法规则为节点的树状结构。 在语法分析的过程中,编译器通常会使用自底向上(Bottom-up)或自顶向下(Top-down)两种不同的构建语法树方式,其选择方式与编程语言的复杂度、语法规则的特点等有关。
3)语义分析
主要任务:根据语法结构分析其含义,并用某中间语言表示出来,也就生成中间代码,或者直接生成目标代码。
语义分析是编译器的第三个阶段,其主要任务是检查源代码语法正确的前提下,对代码进行含义分析,并判定其是否符合语言的语义规范。 语义分析的目的是发现代码中的语义错误,包括类型不匹配、未定义变量或函数、不合法的表达式等。在发现错误后,编译器通常会生成错误消息,并尝试进行错误修复和恢复。 在语义分析的过程中,编译器会对代码中的每个语句、表达式、函数调用等进行分析,判断其是否存在语义错误。具体来说,它会检查以下方面:
1. 变量和类型检查:检查变量是否已定义、是否赋值正确、数据类型是否匹配等。
2. 表达式分析:检查表达式是否具有良好的类型、常量折叠优化等。
3. 函数调用检查:检查函数调用参数数量和数据类型是否与函数定义匹配等。
4. 类型转换分析:检查在表达式、函数参数传递和赋值等过程中是否需要进行数据类型转换等。 在完成语义分析后,编译器会对代码进行优化并生成目标代码,以进行后续的执行和测试。 总之,语义分析是编译器中非常重要的一步,它能够帮助程序员在开发过程中尽早发现代码中存在的问题。通过语义分析,编译器不仅可以检测语法错误,而且可以帮助程序员更好地理解代码含义,提高代码的质量和可靠性。
4)中间代码生成
中间代码生成是编译器的第四个阶段,其主要任务是将源代码转换为一种中间表示形式,以方便后续的代码优化和目标代码生成。 在中间代码生成的过程中,编译器会将源代码转换为一种类似于汇编语言的中间代码,通常是一种抽象的、更高级的指令集。这种指令集与目标机器的特定指令集无关,但它能够表达源代码中的所有语义。
例如,C语言源代码可以被编译器转换为类似于下面的中间代码:
L1: a = 1
L2: b = 2
L3: c = a + b
L4: return c
在中间代码中,每个指令都代表源代码中的一行语句,例如变量赋值语句、算术表达式、条件分支语句等。同时,中间代码还会引入一些额外的指令来处理控制流语句、函数调用和优化等问题。 通过中间代码生成,编译器可以有效地将源代码和目标代码解耦,使得不同的目标平台可以共享同一份中间代码,并进行独立的代码优化和目标代码生成。同时,中间代码还可以方便地进行代码的调试和分析,在开发和测试阶段非常有帮助。 总之,中间代码生成是编译器中非常重要的一步,它为后续的代码优化和目标代码生成提供了基础。通过中间代码生成,编译器能够将源代码转换为一种中间表示形式,方便后续的代码分析、调试和优化。
常见的中间代码形式:逆波兰表示、三元式、四元式以及树形结构等
4)代码优化
代码优化是编译器的第五个阶段,其主要任务是对中间代码进行各种改进和优化,以提高程序的速度、可读性和可维护性。 在代码优化的过程中,编译器会针对中间代码进行各种优化,例如:
1. 常量折叠(Constant Folding):将表达式中的常量计算出结果,并用计算结果替代表达式。
2. 多项式化简(Algebraic Simplification):对表达式进行简化,将多个表达式合并为一个表达式。
3. 公共子表达式消除(Common Subexpression Elimination):避免多次计算相同的表达式,将相同的表达式提取出来,只计算一次,然后重用计算结果。
4. 循环优化(Loop Optimization):根据循环语句的特征改进循环结构或代码块,使得循环能够更快、更稳定地执行。
5. 寄存器分配和指令选择(Register Allocation and Instruction Selection):将中间代码转换为目标机器代码,使得生成代码的效率更高。
通过代码优化,编译器可以使得生成的目标代码更加高效、可读性更好、可维护性更强。优化可以减少程序执行的时间和空间开销,提高程序的性能,同时还可以减少程序出错的可能性,提高程序的可靠性和可维护性。
总之,代码优化是编译器中非常重要的一步,它可以对生成的中间代码进行各种改进和优化,使得后续生成的目标代码更加高效、可读性更好、可维护性更强。通过代码优化,编译器可以大大提高程序的性能和质量,为程序员的开发工作提供更好的支持。
6)代码生成
代码生成是编译器的最后一个阶段,其主要任务是将中间代码转换为目标机器的机器码,并生成可执行文件或动态链接库等可运行程序。
在代码生成的过程中,编译器会进行以下操作:
1. 寄存器分配:将中间代码中的变量和常量映射到目标机器的寄存器、内存地址或其他存储单元中。
2. 指令选择:根据目标机器的指令集和寄存器的分配情况,选择最优的指令序列,生成机器码。 3. 代码重定位:根据可执行文件的格式和目标机器的内存布局,将生成的机器码放置到适当的内存地址上。
4. 代码链接:如果程序需要调用其他函数或库,将生成的目标文件和库文件链接在一起,生成可执行文件或动态链接库。
通过代码生成,编译器可以将中间代码转换为目标机器的机器码,并生成可执行文件或动态链接库等可运行程序。编译器会根据目标机器的硬件特性和操作系统的要求,选择合适的指令序列和内存布局,以获得最优的代码性能和可执行文件大小。
总之,代码生成是编译器中非常重要的一步,它将中间代码转换为目标机器的机器码,并生成可执行文件或动态链接库等可运行程序。通过代码生成,编译器可以根据目标机器的硬件特性和操作系统的要求,生成高效、可靠、可运行的目标代码,为程序员的开发工作提供更好的支持。
7)趟
编译程序的趟指的是编译器在编译源代码的过程中所经过的阶段或步骤。趟(Pass)是编译器的传统术语,用来表示编译器将源代码转换为目标代码的基本步骤。 通常情况下,编译器的趟数是固定的,并且每一趟都会处理特定的任务。不同的编译器具有不同的趟数和任务
总之,编译程序的趟指的是编译器在编译源代码的过程中所经过的阶段或步骤,每一趟都有特定的目标和输出,形成一个完整的编译流程。
四、编译程序开发
1)自编译
自编译(Self-Compiling)是指使用某个程序的源代码,通过编译器等工具自行进行编译的过程。自编译的好处是可以根据自己的需要对程序进行定制,以及确保代码的安全性和可靠性。在软件开发中,自编译也是非常重要的一步,可以检查代码质量和发现潜在的问题。但自编译也需要一定的编译知识和技能,并且要注意编译环境的配置和细节问题。
2)交叉编译
交叉编译(Cross-Compilation)是指在一台计算机上生成另一种计算机上运行的可执行程序的过程。具体地说,交叉编译器可以将源代码编译为可以在目标环境中运行的二进制可执行文件或库,并且不需要在目标环境中运行编译器。这种技术常用于嵌入式系统、手机应用等场景,因为在这些场景下设备资源有限,无法在目标设备上直接编译代码。交叉编译需要特定的编译器和一定的编译知识和技能。
3)自展
自展(Self-hosting)是指一种程序开发方法,即使用一个程序来编写或修改另一个程序,而后者实现了原来的程序。通俗来说,自展是指用一个程序来构建自身的能力。这种方法的优点在于可以提高程序开发的效率和可靠性,因为自展程序可以自动化地进行构建、测试和部署等过程。同时,自展程序还可以带来更好的可维护性和可扩展性。常见的自展程序有编译器、解释器等。
4)移植
移植(Porting)是指将一个软件系统从一个平台或者操作系统移植到另一个平台或者操作系统上的过程。移植通常对于本来只能运行于某个特定平台或者操作系统的软件来说,是一个非常必要的步骤。移植的过程中,需要针对目标平台或者操作系统的差异,重新进行一些软件设计和实现。移植的过程会遇到一些难点和问题,比如不同平台之间的系统调用接口、硬件底层的差异、字节序等问题。移植需要具备相应的技术和经验,同时也需要对于目标平台或者操作系统有充分的理解和了解。
6)自动化
7)前端与后端
在编译器中,前端(Front-end)和后端(Back-end)是指编译器的不同部分。
- 前端(Front-end):指编译器中负责语法分析、词法分析和语义分析等阶段的部分。在前端阶段,编译器会将源代码翻译成一种中间表示形式,例如,语法树、中间代码等。
- 后端(Back-end):指编译器中负责生成目标代码的部分,包括目标机器代码生成、优化和目标代码生成等。在后端阶段,编译器会将中间代码翻译成目标机器代码,以便能够在对应的硬件平台上运行。
前端和后端是编译器中的两个主要部分,它们协同工作,共同完成编译过程。前端解析源代码,并将其转换成中间表示形式;后端将中间表示形式转换成目标代码。前端和后端使用不同的技术和算法,但在整个编译过程中都起着至关重要的作用。同时,前端和后端的性能和质量也会直接影响编译器生成的目标代码的质量和运行效率。
广义:
在计算机科学中,前端(front-end)和后端(back-end)通常用于描述应用程序或系统中的两个主要部分。具体来说:
- 前端通常指用户界面(UI)和用户体验(UX)设计方面的开发工作,包括用户交互、视觉设计、前端编程语言(如JavaScript、CSS和HTML)等技术。前端的目标是实现一个具有良好用户体验的应用程序或网站。
- 后端通常指应用程序或系统的逻辑和数据处理方面的开发工作,包括服务器端编程、数据库管理、安全性和性能优化等技术。后端的目标是实现一个高效、可靠、安全和易于维护的应用程序或系统。
前端和后端通常需要协同工作,在应用程序或系统的不同层面实现不同的功能。例如,在一个Web应用程序中,前端主要负责呈现数据、交互设计等用户界面方面的工作;而后端主要负责数据的处理、存储、安全性和性能优化等方面的工作。在Web应用程序中,前端和后端一起工作,使得应用程序能够为用户提供最好的体验。
五、PL/0语言的编译系统
在学习编译原理时,学习Pascal语言可以帮助你更好地理解和掌握相关的概念和技术,因为Pascal语言是一种结构化的编程语言,与编译原理中的一些概念、原理和方法有很好的对应关系。同时,Pascal语言也充分体现了一些编译原理中的重要概念,比如语法分析、语义分析、类型检查和代码生成等。 虽然Pascal语言不如一些现代编程语言如Python、Java、C++等流行和应用广泛,但是在学习编译原理和算法方面,学习Pascal语言仍然有其价值。因此,学习Pascal语言可能不能算作落后,而是一种有益的经验积累。
PL/0是一种简单的类Pascal语言,常被用于学习编译原理中的编译器设计与实现。PL/0编译系统主要包含两部分:编译器和解释器。 编译器部分:PL/0编译器的主要任务是将源程序转换成目标代码,包括词法分析、语法分析、语义分析、中间代码生成、目标代码生成等过程。编译器首先通过词法分析器将源程序转化为单词流,然后通过语法分析器构建语法树,接下来进行语义分析并生成中间代码,最后进行目标代码生成。编译器的输出是目标代码文件。 解释器部分:PL/0解释器的主要任务是执行目标代码,包括将目标程序装载到内存中、解释执行中间代码、输出结果等过程。解释器的输入是目标代码文件。 PL/0编译系统的设计和实现可以帮助编译原理初学者更好地理解编译器的工作原理和编译过程中的一些关键概念,如语法分析、语义分析、语法制导翻译等。
1)BNF与EBNF
BNF代表巴科斯范式(Backus-Naur Form),是一种表示上下文无关文法的符号约定。BNF常常被用于编程语言的语法描述和编译器设计中。在BNF中,一些特定的符号被用作元字符,例如“::=”表示“定义为”、“|”表示“或”、“<>”表示一个非终端符号,而小写字母或数字表示终端符号。
而EBNF代表扩展巴科斯范式(Extended Backus-Naur Form),是一种基于BNF的语法符号集的扩展标准,具有更多的表达能力和易读性。相比于BNF,EBNF扩展了一些符号,如“[]”表示可选项、“{}”表示重复项、“()”表示分组等等。此外,EBNF还支持更多的元字符,例如“+”表示一个或多个出现、 “?”表示零个或一个出现、“=”表示一致性等。
总的来说,BNF和EBNF都是用于表示上下文无关文法的符号约定,BNF是EBNF的基础,EBNF在BNF的基础上扩展了更多的符号和元字符,提供更高效的语法描述和更高的易读性。
2)PL/0编译程序的结构
PL/0编译程序的结构一般分为四个主要部分:
1. 词法分析部分:将源程序分解为一个个单独的单词(Token),并将它们归类为PL/0的保留字、标识符、常数、运算符或分界符等类型。这个过程也被称为“扫描”或“词法分析”。
2. 语法分析部分:根据PL/0的语法规则,将词法分析部分得到的单词流转换成语法树,以便检查其结构正确性。这个过程也被称为“语法分析”或“解析”。
3. 语义分析部分:检查源程序的语义正确性、类型匹配等问题,并在此基础上生成中间代码。这个过程也被称为“语义分析”或“语义检查”。
4. 代码生成部分:将语法分析部分得到的中间代码转换成机器代码,以便在相应平台上执行。这个过程也被称为“代码生成”。
在PL/0编译程序结构中,这些部分通常都是顺序执行的,并且每个部分都会对前面的部分产生影响。例如,词法分析部分得到的单词流将传递给语法分析部分,语法分析部分得到的语法树将传递给语义分析部分等等。最后,代码生成部分将生成与原语言等效的机器代码,并生成可执行文件。这些部分将合作完成整个PL/0源程序的编译过程。