【问题标题】:How to script input for a Java program如何为 Java 程序编写脚本输入
【发布时间】:2012-07-14 13:14:25
【问题描述】:

我正在编写一个 Java 程序,该程序要求其(技术)用户编写用作输入的脚本;它将这些脚本解释为一系列动作并执行它们。我目前正在寻找实现脚本/配置语言的最干净的方法。我原本打算沿着 XML 路线前进,但所需输入的本质实际上是需要执行的程序化、线性

function move(Block b, Position p) {
    // user-defined algorithm for moving block "b" to position "p"
}

Block a = getBlockA();
Position p = getPositionP();

move(a, p);

等等。 请注意:以上只是一个示例构成我想要实现的确切语法。我仍处于“30,000 英尺视图”设计阶段,不知道我的具体脚本语言最终会是什么样子。我只是提供这个例子来说明它是一个用户必须编写的流程/程序脚本,并且XML 可能不是其实现的最佳候选者。 p>

XML,非常适合分层数据,只是感觉不是这种实现的最佳选择(尽管如果需要我可以强制它工作)。

我对 DSL 一无所知,但我已经开始阅读 Groovy DSL,感觉它们非常适合我的需要。

我的理解是我可以编写一个 Groovy(我在 Groovy 方面比 Scala、JRuby 等更强大)允许用户编写脚本的 DSL(.groovy 文件) 我的程序可以在运行时作为输入执行。

这是正确的,还是我完全误解了 DSL 的意图?如果我错了,有人对我有什么建议吗?如果我是正确的,那么 Java 程序将如何读取和执行 .groovy 文件(换句话说,我的程序将如何“使用”他们的脚本)?

编辑:我开始喜欢 ANTLR。虽然我很想卷起袖子写一个 Groovy DSL,但我不希望我的用户能够编写他们想要的任何旧的 Groovy 程序。我想要我自己的“微语言”,如果用户跳出它,我希望解释器使脚本无效。开始看起来 Groovy/DSL 不是正确的选择,也许 ANTLR 可能是我需要的解决方案...?

【问题讨论】:

  • 您可能还想看看Beanshell
  • @HovercraftFullOfEels,它相当老派,而且(AFAIK)没有积极开发。但这可能符合 Zac 的目的:他发布的示例代码几乎可以复制粘贴并用作 Beanshell 脚本并用于 Java 应用程序。
  • 看看Xtext,用它写DSL很爽(而且还在积极开发中!)
  • @Zac 你似乎(隐隐约约地)误解了 DSL 的目的。它们主要用于在主要的过程语言之上实现声明式的专用语言(例如用于配置)。这并不是说你走错了路。如果您的用户主要编写程序代码,并且您只需要在运行时有一种合理的方式来加载/评估它,那么您可以直接使用 Groovy 并绑定到您的 Java 代码。
  • @ZacHarvey 他们会是常规的 Groovy。但是,基于 Groovy 的 DSL 也是如此。如果您想要限制执行,则需要为其设计的语言/环境。 Lua 通常是一个很好的选择,但我不知道与 Java 集成有多么容易。 (另一种选择可能是使用 Java 代码安全性的东西,但我不知道它是如何工作的,或者它是否可以实现你需要的那种限制。)

标签: java groovy dsl


【解决方案1】:

我认为你走在一条非常好的道路上。您的用户可以使用您的简单 DSL 编写他们的文件,并且您可以通过在运行时评估它们来运行它们。您最大的挑战将是帮助他们正确使用您的 DSL 的 API。除非他们使用 IDE,否则这将非常困难。

Equivalent of eval() in Groovy

【讨论】:

    【解决方案2】:

    是的,您可以编写一个 Groovy 程序来接受脚本作为输入并执行它。我最近使用 groovy 以这种方式编写了一个 BASIC DSL/解释器:

    http://cartesianproduct.wordpress.com/binsic-is-not-sinclair-instruction-code/

    (最后它比 DSL 更具解释性,但这与 Groovy 的特性有关,可能不会影响您 - BASIC 坚持使用 Groovy 难以解析的大写关键字 - 因此必须转换它们小写)。

    Groovy 允许您以各种方式扩展脚本环境(例如,将变量注入绑定并将执行从当前脚本转移到不同的、动态加载的脚本),这使得这变得相对简单。

    【讨论】:

      猜你喜欢
      • 2019-02-13
      • 1970-01-01
      • 2023-01-07
      • 2011-05-29
      • 2020-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      相关资源
      最近更新 更多