【问题标题】:Is it possible to export a DSL compiler created by JetBrains MPS and use it independently (e.g. invoke it from another Java program)是否可以导出由 JetBrains MPS 创建的 DSL 编译器并独立使用(例如从另一个 Java 程序调用它)
【发布时间】:2020-08-14 04:34:50
【问题描述】:

我想构建一个 DSL 并按如下方式使用它:

  • DSL 编译为 Java。
  • 导出 DSL 编译器并将其打包(即作为 JAR),这样我就可以从 Java 应用程序调用 DSL 编译器,将“用我的 DSL 编写的代码”编译成“Java 源代码”(我将使用其他库以编程方式将 Java 编译成字节码)。

我可以使用 JetBrains MPS 构建 DSL 并按照说明导出其编译器吗?如果没有,其他建议是否值得赞赏?

【问题讨论】:

  • Java 本身需要编译。或者你的意思是它编译成 Java 字节码?因为你需要具体。 Java 不被解释,Java 9+ 不再适合 JAR 打包(因为您现在应该使用 jlink 来创建应用程序的自定义运行时映像)。另外,我不是您的律师,我无法在法律上保护您免受任何(可能的)违反 JetBrains 许可证的行为。或 Java 编译器许可证。但我认为您可以使用任何 OpenJDK 编译器。如果你想使用 Oracle 版本,我希望你准备好你的支票簿。
  • 我希望 DSL 编译器能够从“用我的 DSL 编写的代码”编译为“Java 源代码”(我会更新问题)。我见过其他库,可用于以编程方式将 Java 编译为字节码。并感谢提醒您在使用这些工具时调查可能的许可证违规行为。

标签: dsl mps


【解决方案1】:

我在 MPS 支持论坛上提出了这个问题,我得到的答案是无法从 MPS IDE 导出我的 DSL 的编译器(例如 JAR),然后从某个 Java 应用程序调用导出的编译器(想想Java 后端服务)传递代表在我的 DSL 上编写的程序的文本输入。

虽然您可以使用 ant 调用“MPS 代码生成器”(它负责生成目标语言代码,例如 Java,代表输入 DSP 程序),但生成器期望您的“MPS 模型”作为输入DSL 程序(我猜它是某种 AST,例如 DSL 程序的 MPS 内部表示)。但是生成 DSL 程序的“MPS 模型”的唯一方法是使用 Jetbrains 的 MPS IDE(或它的剥离版本,或带有 DSL 插件的 intellij)。 换句话说,在 DSL 中编写/编辑程序并能够编译它们的唯一方法是使用 Jetbrains MPS IDE(或其衍生产品之一)。

Link to the question I posted on MPS Support forum and the answer.

【讨论】:

  • 也许在 MPS 中可以使语言具有足够的自反性来编写交叉编译器?
【解决方案2】:

在我看来,您的问题与此文档条目相距不远:https://confluence.jetbrains.com/display/MPSD32/Building+standalone+IDEs+for+your+languages

【讨论】:

  • 该文档描述了为您的 DSL 创建一个独立的 IDE,并没有描述我如何实现我对创建 IDE 不感兴趣,但只导出 DSL 编译器部分的情况。我打算从另一个 Java 应用程序中以编程方式调用 DSL 编译器。感谢您分享链接。
  • 在我看来,“独立 IDE”是包含“DSL 编译器部分”的“另一个 Java 应用程序”。你可能'''只是'''必须弄清楚有多少 IntelliJ 将作为依赖项出现。
  • 从那篇文章的介绍部分:“术语独立 IDE 指的是 IDE 的精简版本,它只包含给定业务目的所需的那些工件。独立 IDE 提供了一种方便的方法将 DSL 分发给最终用户”这是关于分发 IntelliJ 的精简版本,而不是编写自己的 IDE。
【解决方案3】:

也许您不能直接将其作为 jar 库执行,但可以通过一些 ant 或 gradle 魔术从 ant 任务调用 DSL 编译器(或者,在 MPS 中称为生成器)。可以在https://www.jetbrains.com/help/mps/building-mps-language-plugins.html# 找到有关这方面的文档 我知道它说的是构建插件,但使用了相同的机制。 不过,我不知道为什么要这样做,因为 MPS 的优势在于 IDE 支持和非常先进的多语言集成,而不一定是代码生成。

【讨论】:

    【解决方案4】:

    调用导出的编译器 [...] 传递代表在我的 DSL 上编写的程序的文本输入

    可悲的是,您的想法天生就有缺陷。没有将文本作为输入的 MPS“DSL 编译器”之类的东西。在 MPS 中有 generators 可以将您的 DSL 转换为另一种 MPS 语言,在您的情况下,您的目标语言将是 BaseLanguage(Java 的 MPS 版本)。转换后,Java 源代码生成为 .java 文件,并自动编译为 .class 文件。所以是的,这可以通过内置在 BuildLanguage 中并从 cmd 调用的 Ant 脚本来完成。 但是,生成器不会将输入文本作为输入文本,而是将 AST 作为输入。 AST 是您在 MPS 中“编码”的程序(专有名词将被建模)。

    所以你真正想要的是一个解析器(如果你的语言是文本的并且是可解析的),它有文本作为输入,AST 作为输出。一旦你拥有任何形式的 AST,你就可以将它放入 MPS 模型中。

    请参阅我在 MPS here 中评论了一些可移植性(基本上是导入、导出)的其他答案。我已经(不仅)提到了我正在那里工作的一个项目。它允许将语言和程序导入 MPS。

    如果您根本不想使用 MPS 的 IDE,而是要处理文本,那么它将失去 MPS 作为带有投影编辑器的语言工作台 (LWB) 的优势。也许您应该使用另一个文本 LWB(例如 Xtext)或解析器生成器(例如 ANTLR)。如果解析器生成器中的语法定义让您感到害怕,您可以使用基于模型的解析器生成器,例如 YAJCo(我已经贡献了)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-16
      • 1970-01-01
      • 2012-02-13
      • 1970-01-01
      相关资源
      最近更新 更多