【发布时间】: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 代码安全性的东西,但我不知道它是如何工作的,或者它是否可以实现你需要的那种限制。)