Compilation 编译器如何编译自己?
我在网站上研究咖啡脚本,它有文本 CoffeeScript编译器本身就是用CoffeeScript编写的Compilation 编译器如何编译自己?,compilation,Compilation,我在网站上研究咖啡脚本,它有文本 CoffeeScript编译器本身就是用CoffeeScript编写的 编译器如何编译自己,或者这句话是什么意思?编译器的第一版不能由特定于它的编程语言机器生成;你的困惑是可以理解的。第一个编译器可以构建具有更多语言功能的更高版本的编译器(在新语言的第一个版本中重写源代码)。该版本可以编译下一个编译器,依此类推。下面是一个例子: 第一个CoffeeScript编译器是用Ruby编写的,生成了CoffeeScript的版本1 CS编译器的源代码在CoffeeScr
编译器如何编译自己,或者这句话是什么意思?编译器的第一版不能由特定于它的编程语言机器生成;你的困惑是可以理解的。第一个编译器可以构建具有更多语言功能的更高版本的编译器(在新语言的第一个版本中重写源代码)。该版本可以编译下一个编译器,依此类推。下面是一个例子:
这个过程通常被称为。另一个引导编译器的例子是rustc,它是.的编译器。您已经得到了一个非常好的答案,但是我想为您提供一个不同的视角,希望能对您有所启发。让我们首先确定两个我们都能达成一致的事实:
char s[] = {
'\t',
'0',
'\n',
'}',
';',
'\n',
'\n',
'/',
'*',
'\n',
… 213 lines omitted …
0
};
/*
* The string s is a representation of the body
* of this program from '0'
* to the end.
*/
main()
{
int i;
printf("char\ts[] = {\n");
for(i = 0; s[i]; i++)
printf("\t%d,\n", s[i]);
printf("%s", s);
}
接下来,您可能想知道编译器是如何得知像'\n'
这样的转义序列表示ASCII代码10的。答案是,在C编译器中的某个地方,有一个解释字符文本的例程,其中包含一些识别反斜杠序列的条件:
…
c = next();
if (c != '\\') return c; /* A normal character */
c = next();
if (c == '\\') return '\\'; /* Two backslashes in the code means one backslash */
if (c == 'r') return '\r'; /* '\r' is a carriage return */
…
因此,我们可以在上面的代码中添加一个条件
if (c == 'n') return 10; /* '\n' is a newline */
…生成知道'\n'
表示ASCII 10的编译器。有趣的是,该编译器及其编译的所有后续编译器“知道”该映射,因此在下一代源代码中,您可以将最后一行更改为
if (c == 'n') return '\n';
…它会做正确的事!10
来自编译器,不再需要在编译器的源代码中明确定义。1
这是用C代码实现的C语言特性的一个示例。现在,对每一种语言功能重复这个过程,您就有了一个“自托管”编译器:一个用C编写的C编译器
1论文中描述的情节扭曲是,由于编译器可以被“教导”这样的事实,它也可能被错误教导以难以检测的方式生成特洛伊木马可执行文件,并且这种破坏行为可能会持续存在于受污染编译器生成的所有编译器中 编译器如何编译自己,或者这句话是什么意思 就是这个意思。首先,要考虑的一些事情。我们需要查看四个对象:
- 任意CoffeScript程序的源代码
- 任意CoffeScript程序的(生成的)程序集
- CoffeScript编译器的源代码
- CoffeScript编译器的(生成的)程序集