C语言编译器的来源
关注+星标公众号,不错过精彩内容
编排 | strongerHuang
微信公众号 | 嵌入式专栏
现在的学生,学过编译原理后,只要有点编程能力的都可以实现一个功能简单的类C语言编译器。可是问题来了,不知道你有没有想过,大家都用C语言或基于C语言的语言来写编译器,那么世界上第一个C语言编译器又是怎么编写的呢?这不就是一个“鸡和蛋”的问题吗?
嵌入式专栏
1
嵌入式专栏
2
其中C0属于C1,C1属于C,用C0开发出C1语言的编译器。在C1的基础上设计C语言的又一个子集C2语言,C2语言比C1复杂,但是仍然不是完整的C语言,开发出C2语言的编译器……如此直到CN,CN已经足够强大了,这时候就足够开发出完整的C语言编译器的实现了。
至于这里的N是多少,这取决于你的目标语言(这里是C语言)的复杂程度和程序员的编程能力——简单地说,如果到了某个子集阶段,可以很方便地利用现有功能实现C语言时,那么你就找到N了。
下面的图说明了这个抽象过程:
C语言 |
CN语言 |
…… |
C0语言 |
汇编语言 |
机器语言 |
这张图是不是有点熟悉?对了就是在讲虚拟机的时候见到过,不过这里是CVM(C Language Virtual Machine),每种语言都是在每个虚拟层上可以独立实现编译的,并且除了C语言外,每一层的输出都将作为下一层的输入(最后一层的输出就是应用程序了),这和滚雪球是一个道理。用手(汇编语言)把一小把雪结合在一起,一点点地滚下去就形成了一个大雪球,这大概就是所谓的0生1,1生C,C生万物吧?
嵌入式专栏
3
autoenum restrict unsigned
breakexternreturnvoid
casefloatshortvolatile
charforsignedwhile
constgotosizeof_Bool
continueifstatic_Complex
defaultinlinestruct_Imaginary
dointswitch
doublelongtypedef
elseregisterunion
//共37个
enumunsigned
breakreturnvoid
casefloatshort
charforsignedwhile
goto_Bool
continueif_Complex
defaultstruct_Imaginary
dointswitch
doublelong
elseunion
//共27个
enum
breakreturnvoid
case
forwhile
goto
continueif
defaultstruct
dointswitch
double
elseunion
//共18个
breakreturnvoid
case
forwhile
goto
continueif
default
dointswitch
double
else
//共15个
breakvoid
goto
int
double
//共5个
这已经是简约的极致了。
只有5个关键字,已经完全可以用汇编语言快速的实现了。通过逆向分析我们还原了第一个C语言编译器的编写过程,也感受到了前辈科学家们的智慧和勤劳!我们都不过是巨人肩膀上的灰尘罢了!0生1,1生C,C生万物,实在巧妙!
免责声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。
后台回复『编译器』『嵌入式C语言』阅读更多相关文章。
点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。