5

假设我写了一种编程语言;同名,我称之为lang

为了开始编写lang的漫长旅程,我决定从编写 lang 本身开始。我实际上无法运行它,因为没有什么可以运行自行运行的程序。

因此,我首先用Java为lang编写另一个编译器。这一次,当我完成后,我决定将其转换为字节码,并保留它。我现在有一个可以工作的编译器,它将我所有的语言代码转换成字节码。

所以我决定将我的语言自编译器插入到我刚刚用 Java 制作的编译器中。然后我将自编译器转换为字节码,并丢弃 Java 编译器。我现在有一个lang编译器,纯粹是自己写的,转换成字节码,可以使用了。

这创建了一个可靠的程序,我理解所有这些,但我的问题是,相对于 JVM 的编译器设计,如果我决定发布我的语言的更新怎么办?我该如何更新字节码?我是否只是简单地用旧版本重新编写语言的更新版本?

我问这个是因为这是我想做的。自己编写一种不存在的语言,然后通过首先在 Java 中创建编译器将其引导到 JVM。

这与使用 C++ 所做的相同。编写了带有类的 C,然后在其中编写了 C++,最后放弃了带有类的 C,而使用了自举的 C++。但是,他们到底是如何更新语言的呢?

4

3 回答 3

3

我将从您开发中的两个可能场景中回答这个问题。您可以随时使用任何字节码语言更新虚拟机或语言。

假设首先您想更新您的语言以具有新的语法或更改当前的语义。然后,您将保持当前编译的编译器以lang(编译器A)编写并编辑其源代码,以便它可以正确编译您的新功能。然后你使用旧的编译器编译你的编译器,给你编译器B。如有必要,您现在可以重写编译器以使用新功能,然后使用编译器B对其进行编译,从而为您提供编译器C

如果 JVM 发生变化怎么办?那么在这种情况下,您保留旧版本的 JVM,调整编译器以应对新的字节码更改,然后使用旧版本编译它(这类似于之前的编译器B)。这将为您提供一个可以编译为新字节码但在旧 VM 上运行的编译器。下一步是让它自己编译,现在你有了一个在新 VM 上运行的新编译器(类似于编译器C)。

于 2017-02-16T11:12:50.883 回答
0

第一个lang编译器可以用lang的子集编写。而且您只需要一个子集(引导程序)编译器(甚至是互译器)。这可以用java编写。

后来,可以用lang编写更广泛的编译器。较新的版本也可以。


您甚至可以编写一个将 lang 程序转换为 java 的翻译器,并使用它来创建第一个 lang 翻译器,然后将其转换为字节码编译器。

于 2017-02-16T11:12:11.437 回答
0

我认为您的编译器不是解决此问题的最佳方法。

我会从我的语言的语法开始。

接下来是词法分析器/解析器,用于将我的语言中的表达式转换为抽象语法树 (AST)。AST 是表达式的正确中间表示。

您可以通过编写遍历 AST 的代码生成器为您选择的虚拟机或处理器发出字节码或汇编语言指令。

您的更新发生在哪里?

如果是语言基础,则必须同时修改语法和字节码发射。

如果您正在优化字节码或移植到新处理器,则必须修改代码生成器。

于 2017-02-16T11:10:15.987 回答