【问题标题】:Writing languages for the JVM为 JVM 编写语言
【发布时间】:2017-02-16 11:01:15
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

  • 调试字节码会很痛苦。我建议你将lang 的翻译器写成java 这样你就可以看到它在做什么并调试翻译后的Java。稍后您可以编写一个更高效的编译器直接生成字节码。
  • @Peter Lawrey:很少需要“调试字节码”。如果您生成的类文件具有指定源文件名和指令到行号的映射的调试属性,那么无论它实际上是用哪种语言编写的,您都可以像 Java 源代码一样顺利地调试它。
  • 如果你升级你的语言,你必须只使用以前语言的特性来实现更新的特性。只有在完成之后,您才能开始使用编译器中的新功能。

标签: java compiler-construction jvm jvm-bytecode


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    我不认为你的编译器是解决这个问题的最佳方法。

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

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

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

    您的更新发生在哪里?

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

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

    【讨论】:

    • 谢谢!但是,当您指定语言基础时,当我修改字节码发射时,我应该用 Java 编写发射器,还是以前版本或相关语言的提交?
    • 语法也是语言参考的良好基础。但是,然后您将自己绑定到 java 解析器实现语言,直到解析器是用 lang 编写的。但是+1
    • 我没有说它必须是 Java 解析器。为什么要关心解析器是否是用原始语言编写的?如果你愿意,可以使用野牛。
    【解决方案3】:

    第一个lang编译器可以写成lang子集。而且您只需要一个子集 (bootstrap) 编译器(甚至是 interoreter)。这可以用java写。

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


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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 2011-03-23
      • 2015-08-16
      相关资源
      最近更新 更多