理论教育 编译器设计之路:程序设计语言基础

编译器设计之路:程序设计语言基础

时间:2023-11-04 理论教育 版权反馈
【摘要】:编译器是将一种程序设计语言编写的源程序等价地转换为另一种程序设计语言编写的源程序的系统软件。下面,来谈谈程序设计语言及其编译技术的话题。然而,同样的问题在程序设计语言中却很罕见。当然,这并不意味着程序设计语言中是绝对不存在二义性的。迄今为止,程序设计语言仍是人类与计算机交流的主要途径,它的应用领域也仅限于操纵与控制计算机。经过多年努力,汇编语言、C、Pascal等程序设计语言终于横空出世。

编译器设计之路:程序设计语言基础

Intel公司的David Kuck院士曾经将编译器誉为“计算机科学与技术的皇后”,它是应用与系统之间的一座桥梁。在国内,由于计算机基础科学相对薄弱,人们通常更多投身于应用领域的研究,编译技术并不太受到人们的关注。因此,基于这方面的研究成果也相对较少。除了早期一些大型机的Fortran、Algol编译器之外,并没有真正的产品级编译器。不过,这并不意味着研究编译技术是毫无价值可言的。事实上,作为计算机科学的组成部分之一,编译技术有着极其崇高的地位,其辉煌的历史可能是其他许多学科无法比拟的。众所周知,图灵奖被誉为“计算机界的诺贝尔奖”,自1966年设立至今,54位获奖者中就有16位是由于程序设计语言或编译技术的研究成果而获此殊荣的,见表1-1。虽然有些大师的身影已经渐渐远去,但是他们的研究成果却为人津津乐道。

表1-1 因程序设计语言或编译技术而获图灵奖的科学家

978-7-111-32164-4-Chapter01-1.jpg

注:见《ACM图灵奖:计算机发展史的缩影(1966-2006)》(第三版),吴鹤龄,崔林,高等教育出版社。

从20世纪50年代到80年代末,一些程序设计语言的兴起,为编译技术的发展提供了新的契机。Ada、Fortran、Algol、Pascal、C、C++等高级语言编译器如雨后春笋一般诞生。作为编译领域的经典之作,“龙书”也是撰写于这一时期的,它的出现将原先模糊的理论体系与实现技巧完全梳理清晰了。正在人们隐约感到编译技术(尤其是前端技术)己相对成熟之际,一个崭新的时代正悄然来临。自20世纪90年代至今,计算机硬件体系的飞速发展,把编译技术的研究推向了新的高峰。

编译器是将一种程序设计语言编写的源程序等价地转换为另一种程序设计语言编写的源程序的系统软件。习惯上,将前者称为源语言,而将后者称为目标语言。读者应该对语言并不陌生,汉语、英语、C、Java等都是语言。那么,它们的联系与区别是什么呢?

大干世界的语言一般可以分为两类,即自然语言和人工语言。自然语言就是日常生活中使用的语言,如汉语、英语。自然语言通常是在交流过程中逐渐完善的,并不是刻意定义的。人工语言则是为了特定目的、用途,而人为创造出来的语言。例如,在计算机程序设计中使用的语言、工程技术中的符号、图形语言等。实际上,读者可以将人工语言理解成为解决某一特殊问题而定义的一种语言,例如C、Java等就是为了解决计算机程序设计而定义的人工语言。不过,自然语言与人工语言之间并非如人们所想象的那样存在着严格的界限。虽然自然语言没有太多的人为主观因素,但是它确实也是由人类创造的。因此,读者只需了解这两个概念即可,不必过多深究。

早在20世纪50年代,计算机科学家就开始对语言处理进行了深入的研究,其中包含最重要的两个领域:一是自然语言理解与处理,二是程序设计语言及其编译技术。前者主要研究计算机如何才能正确识别与处理自然语言及其语义。而后者主要研究如何设计一种人工语言,使之有效地完成人与计算机之间的无障碍交流,计算机之所以能普及到干家万户与程序设计语言的发展是分不开的。不过,两者的研究至今仍然尚待完善,例如,至今人类还无法使用计算机自动完成英语句子到汉语句子准确无误的翻译。这主要是由于无法让计算机准确理解输入英语句子的语义,同时,也无法让计算机将预定语义使用汉语表达输出。这就需要在自然语言理解与处理领域的继续探索。

自然语言理解与处理不是本书的研究对象,笔者不多作讨论。下面,来谈谈程序设计语言及其编译技术的话题。这方面的研究主要包括:程序设计语言设计与定义、高级语言编译器设计、编译优化技术、并行编译技术、嵌入式编译技术、动态编译技术等。读者阅读完本书之后,可以根据个人兴趣选择其中某些领域作深入学习与研究。(www.daowen.com)

程序设计语言是一种人工语言,而人工语言的一个重要特点就是人们可以对语言作一些严格的规定,从而不必过多关注语言表达形式的不确定性。例如,在C语言中,表达式a==10只能用于描述“变量a是否等于10”这一种语义。然而,在自然语言中,一个句子存在两种以上语义的情况并不罕见。例如,“我看见他太激动了。”这个句子表达的含义到底是什么?

可以理解为: 我看见他后,我太激动了。

也可理解为: 我看见他时,他非常激动。

这里“看见”的宾语选择使句子存在二义性。然而,同样的问题在程序设计语言中却很罕见。例如,在C语言中,对于a+++b这样的表达式,读者可能会疑惑运算结果到底应该是(a++)+b还是a+(+十b)。但根据C语言的约定,运算结果一定是(a++)+b。由此可见,在设计一门程序语言及其编译器时,避免二义性是设计者考虑的首要因素。至于为什么一定是这样的结果呢?当学习完第2章,读者一定会了解C语言这一约定的现实意义与必要性。当然,这并不意味着程序设计语言中是绝对不存在二义性的。以C语言为例,(++a)+(++a)的取值就将因编译器而异。

迄今为止,程序设计语言仍是人类与计算机交流的主要途径,它的应用领域也仅限于操纵与控制计算机。从第一台计算机诞生之日起,人类就始终在探索一种有效的方式与计算机进行对话交流,使之能为人类服务。虽然时隔数十年,计算机能识别与处理的语言仍然是二进制形式的机器语言描述的源程序。当然,不可否认二进制机器语言的优点非常多,但机器语言的易用性差也是不可回避的。即使是计算机专家想直接使用机器语言与计算机进行交流也是非常困难的。在20世纪50年代,计算机科学家们就已经意识到必须解决这一棘手的问题,否则计算机将无法得到普及。经过多年努力,汇编语言、C、Pascal等程序设计语言终于横空出世。根据语言的形式与特点,习惯上,将机器语言与汇编语言(一种比较接近机器语言的程序设计语言)称为低级语言,将其余的C、Pascal之类的语言称为高级语言。读者必须注意,低级语言与高级语言之分并不是说明语言本身的优劣,仅仅是说明语言的形式与机器语言的相似程度。所谓低级语言指的是与机器语言比较类似的语言,而高级语言指的是与机器语言差别较大而与自然语言比较类似的语言。由于这些非机器语言的诞生,也就出现了将非机器语言等价翻译成机器语言的需求。显然,将非机器语言翻译成机器语言的工作不能由手工完成,否则,非机器语言的产生就没有任何意义了。因此,人们试图借助于一个程序工具自动完成翻译工作。根据语言不同,翻译工具的复杂程度也不尽相同。比如,汇编语言比较接近机器语言,所以其翻译工具较易实现。而高级语言与机器语言差别较大,所以其翻译工具的实现也较为复杂。习惯上,将前者称为汇编器,而将后者称为编译器。当然,有些书上对于汇编器与编译器并没有严格区分,都将其称为编译器,反正这只是一个名词而己,读者不必深究。编译器的源语言是一种较为高级的程序设计语言,而目标语言可以是汇编语言、机器语言或者另一种高级语言。笔者必须澄清一点,人们普遍认为编译器的目标语言就是低级语言,这个观点的确没有错,但并不完整。实际上,有些编译器的目标语言可能是某一种己存在的高级语言,例如,第一个由Bjarne Stroustrup开发的C++编译器的目标语言就是当时的C语言。假设未来的计算机CPU能直接处理C或者Java语言,那么,低级语言、高级语言及编译器的概念也将被重新诠释。

今天,虽然计算机的CPU可以达到天文级的处理速度,但是识别的指令数量却不会超过1000条(PC的指令规模一般只有300-500条左右)。无论多么深奥、华丽的高级语言源代码最终必将被这近干条机器指令等价替换。相对于自然语言而言,程序设计语言的表达能力要小得多。不过,程序设计语言也有其自身的特性,比如,程序设计语言必须简单易学。不可能要求程序员用十年磨一剑的精神像学习英语一样去学习C语言。过于复杂的语言并不是经典的程序设计语言,更不能广为流传。在程序设计语言发展的历程中,这种例子并不罕见。

以上主要讨论了语言及程序设计语言的一些基本常识。程序设计语言的设计是一门技术,更是一门艺术,优秀的程序设计语言可以广为流传数十年之久。实际上,Algol、Lisp、 Fortran、 Pascal、 C,Smalltalk、 APL,ML,Simula、 Modula-l/2、PL360等经典语言都是历经了时间的考验才传承至今的。设计程序设计语言及编译器是一项富有挑战性且能带来无限成就感的工作,希望本书能引领读者进入程序设计语言的殿堂。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈