编译原理学习
语言处理器
语言处理器就像是一个加工车间,某种程序设计语言编写的程序经过它的加工处理后,变成计算机可以执行的形式。语言处理器通常分为两种常见的形式,一是编译器,二是解释器。
编译器(Compiler)就像是一个翻译员,他将自己阅读到的程序,翻译成一个等价的,用另一种语言编写的程序。在这个过程中,他所阅读到的程序称之为 源语言,翻译成的语言称为 目标语言。整个过程如下:
源程序 -> [编译器] -> 目标程序
如果目标程序是一个可以执行的程序,那么它就可以被调用,来处理输入,产生输出。
输入 -> [目标程序] -> 输出
除了翻译的职责外,编译器还承担着发现源程序中的错误的责任。
其次就是解释器(Interpreter),跟编译器的翻译相比,解释器就像是一个同声传译员,他在接受到源程序之后,就会立即翻译成目标语言,同时开始执行。
输入 & 源程序 -> [解释器] -> 输出
编译器与解释器相比,由编译器产生的程序执行起来速度要比解释器快,以为在运行时不需要在依赖编译器或者额外的程序。但于此同时,由于解释器是逐行处理的,因此在错误诊断上的效果更加好。
完整的处理过程
创建一个可执行的目标程序,不仅需要编译这一道处理,往往还需要其他的一些程序。
一个程序,根据设计,往往会被分成好几个模块,源代码散落在多个文件中,这时就需要一个程序来收集源代码文件,将他们聚合在一起。预处理器就是承担这个责任的。预处理器就像是一个装订工人,将各地的纸张收集起来,装订成册,有时候还需要根据指导手册修改纸上的内容(根据宏生成源程序的代码)。
在完成装订之后,这些“册子”就会作为输入,交给编译器去做翻译。在完成翻译后,通常会产生一本“汇编语言”的书籍。
然后,“书”会被交给汇编器(assembler)去做处理,在这之后的成品,就是可以重新定位的机器代码。
由于一个大程序经常会被分成多个部分编译,因此,可重新定位的机器代码有必要和其他的机器代码连接到一起。一个文件中,可能有着另一个文件中的地址。在这时,链接器(linker)就会站出来,根据各个文件的索引要求,把他们相互链接到一起。
最后,加载器(loader)就像运输工一样,负责把所有的执行目标文件送到到内存中,然后执行。