bootstrap 它是编译器所需的最小语言功能子集是什么?
What's the smallest subset of language features you need to bootstrap it's compiler?
一种语言(受 C 启发)作为一种子语言,可以用来为整个语言编写编译器,其绝对必要的核心特性是什么?
你需要一个while
循环,if
,一个true整数变量,以及一种读写文件的方法。而已。 (事实上 ,文件读写部分是很好的,但不是绝对必要的 - 你只需要它来将信息传入和传出程序。如果你可以读写文件,那么你就不需要不再需要整数变量,因为您可以将该文件用作临时存储。)
while
, if
和一个整数变量是图灵完备的,即它可以计算任何图灵可计算的函数。编译器是一个图灵可计算的函数。不能接受任何输入或产生任何输出的编译器非常无聊,因此您需要有一种方法来读取一些输入并写入一些输出。
有两种方法可以解释您的问题:作为理论计算机科学问题;并且,作为一个实际的工程问题。
已经有偏理论答案的答案了。所以,我打算更实际一点。
我认为您将需要整数、指针、变量、if 语句、循环语句和函数。正如另一个 post 指出的那样,您需要有某种方法来读取文件以获取要编译的源代码并写入文件以保存生成的程序集或目标代码。
我建议您查看 Small C compiler. It's a compiler for a subset of C that is able to compile itself. If you look at the Wikipedia page for Small C,您会看到已经出版了一些关于编译器的书籍。虽然这些书已经绝版,但您也许可以找到一本可用的二手书。
您可以定义由 20 行奇数行组成的可引导元编译器来执行此操作。 MetaII compiler 是 1963 年的一个特别好的例子 。 我在 1970 年代从 MetaII 引导了更大的编译器作为基础。
这些元编译器需要能够解析元编译器描述(尤其是它们自己的,因此可以进行引导),它定义了 EBNF 语法(测试输入字符串,扫描下一个标记,...)和一组生成器操作(输出文字字符串、输出最后扫描的标记、输出生成的标签)。您几乎可以用任何语言实现一个库,以在任何过程语言中通常用几百行来实现对此的支持。
以下是 MetaII 的自我描述,直接摘自原始论文:
.
是的,这就是整个该死的事情。 (针对真正动机的练习reader:你可以简化最小支持指令集,以及这个描述)。
这里有一个关于如何 build/understand 这个 gem in JavaScript 的漂亮教程:MetaII Tutorial。
80 年代圣克鲁斯大学的研究生道格·米歇尔斯 (Doug Michels) 将这一点发挥到了极致。如果将语言标记编码为单个字符,则可以定义一个可引导的元编译器,该编译器可以在 80 个字符中进行自我描述。想看详细的,得去Santa Cruz拿论文。
一种语言(受 C 启发)作为一种子语言,可以用来为整个语言编写编译器,其绝对必要的核心特性是什么?
你需要一个while
循环,if
,一个true整数变量,以及一种读写文件的方法。而已。 (事实上 ,文件读写部分是很好的,但不是绝对必要的 - 你只需要它来将信息传入和传出程序。如果你可以读写文件,那么你就不需要不再需要整数变量,因为您可以将该文件用作临时存储。)
while
, if
和一个整数变量是图灵完备的,即它可以计算任何图灵可计算的函数。编译器是一个图灵可计算的函数。不能接受任何输入或产生任何输出的编译器非常无聊,因此您需要有一种方法来读取一些输入并写入一些输出。
有两种方法可以解释您的问题:作为理论计算机科学问题;并且,作为一个实际的工程问题。
已经有偏理论答案的答案了。所以,我打算更实际一点。
我认为您将需要整数、指针、变量、if 语句、循环语句和函数。正如另一个 post 指出的那样,您需要有某种方法来读取文件以获取要编译的源代码并写入文件以保存生成的程序集或目标代码。
我建议您查看 Small C compiler. It's a compiler for a subset of C that is able to compile itself. If you look at the Wikipedia page for Small C,您会看到已经出版了一些关于编译器的书籍。虽然这些书已经绝版,但您也许可以找到一本可用的二手书。
您可以定义由 20 行奇数行组成的可引导元编译器来执行此操作。 MetaII compiler 是 1963 年的一个特别好的例子 。 我在 1970 年代从 MetaII 引导了更大的编译器作为基础。
这些元编译器需要能够解析元编译器描述(尤其是它们自己的,因此可以进行引导),它定义了 EBNF 语法(测试输入字符串,扫描下一个标记,...)和一组生成器操作(输出文字字符串、输出最后扫描的标记、输出生成的标签)。您几乎可以用任何语言实现一个库,以在任何过程语言中通常用几百行来实现对此的支持。
以下是 MetaII 的自我描述,直接摘自原始论文:
是的,这就是整个该死的事情。 (针对真正动机的练习reader:你可以简化最小支持指令集,以及这个描述)。
这里有一个关于如何 build/understand 这个 gem in JavaScript 的漂亮教程:MetaII Tutorial。
80 年代圣克鲁斯大学的研究生道格·米歇尔斯 (Doug Michels) 将这一点发挥到了极致。如果将语言标记编码为单个字符,则可以定义一个可引导的元编译器,该编译器可以在 80 个字符中进行自我描述。想看详细的,得去Santa Cruz拿论文。