前导知识
T形图
参考这里
注意这篇文章有一点问题,在它的评论区里有人讲。
讲一个我的体会来帮助理解T形图:
关于结构:左上的T形图是C实现的,它的C要由机器码实现,所以它右下角需要加上一个。左边和中间的两个共同作用的结果,要写到右上角,也就是右上角的图。(右下面是要用的,右上面是实现的等效的效果)
关于来源和目的:先看右上角的目标,Source是Java, Target是机器码,Implement是机器码。这3个的由来就是分别对应相同颜色框框起来的(蓝色的对应蓝色的,紫色的对应紫色的,红色的对应红色的)。
关于过程:多级编译的目的是,尽可能利用已有的编译器的组合来实现目的编译器,而不是再次开发。这类似代码的复用。
为什么会有多级编译和移植的问题:使用机器代码来开发编译器比较麻烦,不容易做而且不便维护移植,所以尽量利用高级语言来开发编译器。 同时,尽量尝试组合使用已有的机器代码开发的编译器。
多级编译
类似上图的场景,不再赘述。
移植
说明:对于一个值分别为S T I的T形图(用I实现的S到T的编译器),用语言描述为S->I->T,如上图左上角的T形图就是Java->C->机器码。
现在有A B两种机器,已有L->A->A, 实现L->B->B.(已有用A实现的L到A的编译器,得到用B实现的L到B的编译器)
过程:
明确目标:L->B->B
已有条件:L->A->A(已知的高级语言L,能在A机器上编译运行)
原则: 尽可能利用高级语言L实现所需要的中间编译器
详细步骤:首先用L实现几个中间件:L->L->B A->L->B B->L->A(有时候不清楚哪些中间件有用哪些没用,那就直接都列出来)
首先利用高级语言L实现L->L->B
L->L->B
L->A->A
得到了
L->A->B(这个虽然实现语言是机器代码A,但是它不是真的自己做的,而是组合得到的)
基于上面得到的L->A->B
L->L->B
L->A->B
得到了
L->B->B(也就是目标)
整个过程,自己只做了L->L->B
② L->A->A是已有的,只有① L->L->B是用高级语言L自己实现的。
①②结合相当于②右上角的③。
再用一次①,①③的组合相当于③右上角的④.
总结来说,只有①是自己实现的,而②是已知的。通过特定的组合,实现了编译器的移植:原来只有A机器能编译L语言,现在有了④,B机器也能编译L语言。