你知道第一个C语言C++编译器是如何诞生的吗( 三 )

可是问题来了 , 不知道你有没有想过 , 大家都用 C 语言或基于 C 语言的语言来写编译器 , 那么世界上第一个 C 语言编译器又是怎么编写的呢?这不是一个“鸡和蛋”的问题……

还是让我们回顾一下 C 语言历史:1970 年 Tomphson 和 Ritchie 在 BCPL(一种解释型语言)的基础上开发了 B 语言 , 1973 年又在 B 语言的基础上成功开发出了现在的 C 语言 。 在 C 语言被用作系统编程语言之前 , Tomphson 也用过 B 语言编写过操作系统 。 可见在 C 语言实现以前 , B 语言已经可以投入实用了 。 因此第一个 C 语言编译器的原型完全可能是用 B 语言或者混合 B 语言与 PDP 汇编语言编写的 。 我们现在都知道 , B 语言的执行效率比较低 , 但是如果全部用汇编语言来编写 , 不仅开发周期长、维护难度大 , 更可怕的是失去了高级程序设计语言必需的移植性 。 所以早期的 C 语言编译器就采取了一个取巧的办法:先用汇编语言编写一个 C 语言的一个子集的编译器 , 再通过这个子集去递推完成完整的 C 语言编译器 。 详细的过程如下:

先创造一个只有 C 语言最基本功能的子集 , 记作 C0 语言 , C0 语言已经足够简单了 , 可以直接用汇编语言编写出 C0 的编译器 。 依靠 C0 已有的功能 , 设计比 C0 复杂 , 但仍然不完整的 C 语言的又一个子集 C1 语言 , 其中 C0 属于 C1 , C1 属于 C , 用 C0 开发出 C1 语言的编译器 。 在 C1 的基础上设计 C 语言的又一个子集 C2 语言 , C2 语言比 C1 复杂 , 但是仍然不是完整的 C 语言 , 开发出 C2 语言的编译器……如此直到 CN , CN 已经足够强大了 , 这时候就足够开发出完整的 C 语言编译器的实现了 。 至于这里的 N 是多少 , 这取决于你的目标语言(这里是 C 语言)的复杂程度和程序员的编程能力——简单地说 , 如果到了某个子集阶段 , 可以很方便地利用现有功能实现 C 语言时 , 那么你就找到 N 了 。 下面的图说明了这个抽象过程:

推荐阅读