编程语言实现了自举是什么含义

2019-12-24 11:15:47 +08:00
 pythonee
假设语言 x
那么它的编译器是 x 语言编写的,那么编译器的编译器也是用 x 编写的,那么谁来编译这个“编译器的编译器”呢
感觉是无穷尽也

应该最小的那个不可再分的是用别的低级语言写的吧,那么还可称自举吗
9301 次点击
所在节点    程序员
30 条回复
IsaacYoung
2019-12-24 11:16:59 +08:00
ljpCN
2019-12-24 11:17:20 +08:00
最小的不可再分的是不需要编译的,纸带打孔直接执行就行了
lambdaq
2019-12-24 11:17:40 +08:00
最老的肯定是手写的。
momocraft
2019-12-24 11:19:50 +08:00
这语言又不是只能有一个编译器

你可以用 tcc 编译 gcc1 用 gcc1 编译 gcc2 同样叫自举
huobazi
2019-12-24 11:20:19 +08:00
最早那版肯定是别的语言写的
levelworm
2019-12-24 11:21:54 +08:00
应该是其他语言比如汇编写个最小集合出来,然后用这个最小集合一点点加上去。具体技术细节就不知道了。
pythonee
2019-12-24 11:56:32 +08:00
@momocraft
@huobazi
@levelworm

应该是这个样子
hehheh
2019-12-24 12:04:09 +08:00
最早的是打孔机,往后越来越高级。现在的编译过程就是一个文本分析,不过做的工作比这个简单的词多得多。

具体点的话,最早的 c++编译器是用 c 实现的。c 最早的编译器应该是用汇编写的,汇编最早的编译器可能是用插线板插出来的。。。
secondwtq
2019-12-24 12:42:06 +08:00
Rust 编译器最开始是 OCaml 写的——得到”OCaml 写的 Rust 编译器“,为简洁我们把这个编译器称为 P
注意 P 不需要做的非常完善,也不需要实现所有计划中的语言特性,只要能编译一些基本的程序就行,我们把 P 所实现的”原始版本的 Rust 语言”称为 R0

等 P 做到能用的程度,就用 R0 来写 R0 自己的编译器,我们把这个编译器的源码称为 S0,S0 可以直接使用 P 编译得到 E’(注意这里我们把源码和编译器分开了)

由于 E’ 也实现了 R0 语言,因此可以用 E’ 编译 S0,得到 E0

这时我们说 R0 实现了自举。
注意虽然一般默认 OCaml 是 AOT 编译的,但是 OCaml 也可以解释执行,P 也可以使用 JavaScript 等纯解释的语言实现,虽然 JavaScript 是比 Rust 更高层的语言,但是 P 仅用于实现 bootstrap,具体用什么语言实现不重要

在得到 E0 之后,P 就可以不要了,之后的开发全部在 S0 上进行(你现在去 Rust 的 GitHub 翻历史还能找到早期的 OCaml 编译器,不过在 bootstrap 之后早就被删了),之后编译器的第 n 个迭代版本的源码和可执行文件我们称为 Sn/En

注意此时 R0 依然是一个原始版本的语言,在完善语言设计和编译器实现的过程中会加入新特性或做出破坏兼容性的修改,而编译器的代码 Sn 本身可能也会使用到新特性,这时必须保证 E(n-1) 能够编译 Sn,也就是你不能一边实现新特性,一边在新特性的实现代码中使用新特性
secondwtq
2019-12-24 12:44:02 +08:00
另外楼主可以去看下 Futamura Projection …… 更绕,但是 Java 几年前靠这个实现了自举
colors
2019-12-24 12:44:27 +08:00
0.拿 c 写一个 go 语言的编译器 C0, 这时候你就能编译 go 代码了
1.用 go 语言写了个编译器, 用 C0 编译成一个可执行的文件, 这个就是 C1
2.有了 C1,就可以把 C0 抛弃了, 这时候就算实现了自举
Kaiv2
2019-12-24 12:52:03 +08:00
打铁的把铁打成打铁工具打铁🐶
wizardoz
2019-12-24 12:58:32 +08:00
先有鸡还是先有蛋的问题,不管先有哪个,但是这个世界上一旦出现了其中一种,它就可以无穷延续下去了
geelaw
2019-12-24 13:05:58 +08:00
考虑语言 X 和已经有的语言 Y。

用 Y 写出 X 的编译器 A,用 Y 的编译器编译 A 得到 U,再用 X 写出 X 的编译器 B,用 U 编译 B 得到 V,再用 V 编译 B,如果得到的结果二进制等于 V,则完成了自举,此时 V 既可以看成 Y 的编译器 - U - V 产生的,也可以看作 V 自己产生的。
fancy111
2019-12-24 13:41:12 +08:00
你弯绕错了。
反正记住一点,所有语言都得变成 01 机器码,然后上面随便你什么语言实现了这个,再往上就可以自举了。比如 X 语言自身实现转机器码的操作,那么 X1、Y、Z 语言就能利用 X 语言进行编译。
Cu635
2019-12-24 14:12:15 +08:00
@hehheh
打住,汇编就已经是机器码了,汇编跟机器码基本上就是一一对应的,不存在“编译”的问题,你看到的那些字母组合叫做“助记符”,顶多有“展开”。
hehheh
2019-12-24 14:37:26 +08:00
@Cu635 汇编是机器码?机器不用编译器能看懂 mov ?机器能看懂 add? 求问哪家的机器这么厉害?
不存在编译的多的去了,python 也不存在编译,所以 python 也是机器码?
ac2sherry
2019-12-24 14:44:18 +08:00
@hehheh @Cu635
从理解的角度讲可以等价,每一行汇编都可以直接翻译成对应的机器码。不过编译器是存在的,比如 nasm.exe 。
qinliming
2019-12-24 15:05:30 +08:00
@ac2sherry 这叫 assembler 叫做汇编器,编译器是 compiler
misaka19000
2019-12-24 15:10:48 +08:00
月经贴

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/631785

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX