编译器自举和移植
来源:互联网 发布:理工大学网络教育 编辑:程序博客网 时间:2024/04/28 03:40
编译器自举和移植
有个著名的问题:Mommy, where do compilers comefrom?要解决这个问题,首先来看看T-Diagram。可以将编译器用一个T形图来表示:
---------| S T |
--- ---
| I |
---
其中,S表示Souce Language,T表示Target Language,I表示ImplementationLanguage。
根据这个图,可以得到两种组合:
1、 由I实现的将S翻译成A的编译器和将A翻译成T的编译器联合起来工作,可以实现S到T的编译。这不是很有意思的组合。
------------------
| S A | A T |
--- ------ ---
| I | | I |
--- ---
2、由I实现的将S翻译成T的编译器(compiler C1),由H实现的将I翻译成K的编译器的组合(compilerC2)。这个组合比较有意思:可以用C2去编译C1(将其实现语言从I翻译成K),这样就得到由K实现的将S翻译成T的编译器(compilerC3):
--------- ---------
| S T | | S T |
--- ---------- ---> --- ---
| I | I K | | K |
------- --- ---
| H |
---
这便是我们所感兴趣的:编译器的编译器。
而一个程序要在某台机器上运行时,其实现语言必须与相应的机器语言匹配。例如在x86平台上,能执行的程序只能是x86机器语言:
------------------
\ Program /
\ /
-------------
| X86 |
-------------
| X86 |
-------------
让我们将T形图和上图联系起来看,以C为例(假定已有x86的C编译器):
-------- -------- ---------
\ Hello / \ Hello / \ Hello /
----------------------- -------
| C | C x86| x86 | ---> | x86 |
--------- ---------- -------
|x86| | x86 |
---- -------
上图表示用C写的Hello程序可以在C“机器”上运行,然而这不是我们想要的——在x86机器上运行。于是使用实现语言为x86的编译器(其可执行代码)编译形成x86语言,这样就可以运行了。
根据上面的第2条(编译器的编译器)以及程序的执行,我们可以得出,要想得到在M机器上运行的S语言编译器,可以使用S语言来编写(用M语言也可以,然而太麻烦)。但还是需要用M语言写一个具有很小功能的S编译器,然后用其去编译加入了更多功能的编译器,然后用编译出来的更多功能的编译器去编译,这样就得到了最终需要的编译器,这便是自举。
--------- ---------
| S M | | S M |
--- ---------- ---> --- ---
| S | S M | | M |
------- --- ---
| M |(微型S编译器)
---
用S编写S的编译器还有一个好处,那就是方便移植,并且能产生交叉编译器。假定要编译K机器语言的S编译器,只需要将目标语言替换成K,然后用已有的S语言编译器来编译:
--------- ---------
| S K | | S K |
--- ---------- -> --- ---
| S | S M | | M |(运行在M机器上的编译器,即交叉编译器)
------- --- ---
| M |
---
有了交叉编译器,就可以编译在K上运行的S编译器了:
--------- ---------
| S K | | S K |
--- ---------- -> --- ---
| S | S K | | K |
------- --- ---
| M |
---
PS
这个知识实在是简单又基础,主要是觉得很有意思才在这里说说。整个GCC(编译器及交叉编译器)就是用自举和移植产生的,对此RMS有详细的说明。——当然,也有很多编译器不是这样写出来的——用另一种语言编写的。可是,“Mom,where does the compiler needed come from?”实在不愿意贴图了,就用字符代替了,懒:)
参考
Compiler Construction Principles and Practice, by Kenneth C.Louden
"Mommy, where do compilers come from?", by anonymous.
Copyleft (C) 2007, 2008 raof01.
- 编译器自举和移植
- 编译器"自举与移植"原理
- 编译原理--编译器的自举与移植
- 编译器自举
- 编译器之自举
- 编译器自举笔记
- 米勒效应和自举
- 一步步前进的重要性(兼谈编译器的自举)
- 自举
- 自举
- 自举
- 自举电路、自举电容
- 自举?只不过是电容和二极管捣的乱
- BOOTP 自举协议
- WINCE 注册表自举
- 注册表自举
- 自举(bootstrap)
- 注册表自举
- web应用中不可少的json的使用
- Qt简单实例[自用].Ubuntu平台
- 生死游戏(未完待续)
- 编辑距离、拼写检查与度量空间:一个有趣的数据结构
- 二进制颜色代码大全(含图)
- 编译器自举和移植
- 写一个函数,检查字符里面是否是有整数,如果是,返回其整数值
- C++模板详解
- 神秘常量复出!用0x077CB531计算末尾0的个数[Matrix67]
- C的关键字——const的理解和用法
- 储存数据
- 位运算简介及实用技巧(一):基础篇[Matrix67]
- 委托和事件的区别
- 位运算简介及实用技巧(二):进阶篇(1) [Matrix67]