在 Java 中创建自然 DSL 的最佳工具是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/144339/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What would the best tool to create a natural DSL in Java?
提问by kolrie
A couple of days ago, I read a blog entry (http://ayende.com/Blog/archive/2008/09/08/Implementing-generic-natural-language-DSL.aspx) where the author discuss the idea of a generic natural language DSL parser using .NET.
几天前,我阅读了一篇博客文章(http://ayende.com/Blog/archive/2008/09/08/Implementing-generic-natural-language-DSL.aspx),其中作者讨论了一个使用 .NET 的通用自然语言 DSL 解析器。
The brilliant part of his idea, in my opinion, is that the text is parsed and matched against classes using the same name as the sentences.
在我看来,他的想法的绝妙部分是使用与句子相同的名称对文本进行解析和匹配。
Taking as an example, the following lines:
以以下几行为例:
Create user user1 with email [email protected] and password test Log user1 in Take user1 to category t-shirts Make user1 add item Flower T-Shirt to cart Take user1 to checkout
Would get converted using a collection of "known" objects, that takes the result of parsing. Some example objects would be (using Java for my example):
将使用“已知”对象的集合进行转换,该集合需要解析的结果。一些示例对象将是(在我的示例中使用 Java):
public class CreateUser {
private final String user;
private String email;
private String password;
public CreateUser(String user) {
this.user = user;
}
public void withEmail(String email) {
this.email = email;
}
public String andPassword(String password) {
this.password = password;
}
}
So, when processing the first sentence, CreateUser class would be a match (obviously because it's a concatenation of "create user") and, since it takes a parameter on the constructor, the parser would take "user1" as being the user parameter.
因此,在处理第一句话时, CreateUser 类将是一个匹配项(显然是因为它是“create user”的串联),并且由于它在构造函数上接受一个参数,解析器会将“user1”作为用户参数。
After that, the parser would identify that the next part, "with email" also matches a method name, and since that method takes a parameter, it would parse "[email protected]" as being the email parameter.
之后,解析器将识别下一部分“with email”也与方法名称匹配,并且由于该方法接受一个参数,因此它会将“[email protected]”解析为电子邮件参数。
I think you get the idea by now, right? One quite clear application of that, at least for me, would be to allow application testers create "testing scripts" in natural language and then parse the sentences into classes that uses JUnit to check for app behaviors.
我想你现在明白了,对吧?至少对我而言,一个非常明确的应用是允许应用程序测试人员用自然语言创建“测试脚本”,然后将句子解析为使用 JUnit 来检查应用程序行为的类。
I'd like to hear ideas, tips and opinions on tools or resource that could code such parser using Java. Better yet if we could avoid using complex lexers, or frameworks like ANTLR, which I think maybe would be using a hammer to kill a fly.
我想听听有关可以使用 Java 编写此类解析器的工具或资源的想法、技巧和意见。如果我们能避免使用复杂的词法分析器或像 ANTLR 这样的框架更好,我认为这可能是用锤子杀死苍蝇。
More than that, if anyone is up to start an open source project for that, I would definitely be interested.
更重要的是,如果有人准备为此启动一个开源项目,我肯定会感兴趣。
回答by Joe Skora
Considering the complexity of lexing and parsing, I don't know if I'd want to code all that by hand. ANTLRisn't that hard to pickup and I think it is worthing looking into based on your problem.If you use a parse grammar to build and abstract syntax tree from the input, its pretty easy to then process that AST with a tree grammar. The tree grammar could easily handle executing the process you described.
考虑到词法分析和解析的复杂性,我不知道是否要手动编写所有代码。 ANTLR并不难上手,我认为根据您的问题值得研究一下。如果您使用解析语法从输入中构建和抽象语法树,那么使用树语法处理该 AST 非常容易。树语法可以轻松处理执行您描述的过程。
You'll find ANTLR in many places including Eclipse, Groovy, and Grails for a start. The Definitive ANTLR Referenceeven makes it fairly straightforward to get up to speed on the basic fairly quickly.
您会在许多地方找到 ANTLR,包括 Eclipse、Groovy 和 Grails。 Definitive ANTLR Reference甚至使快速上手基本知识变得相当简单。
I had a project that had to handle some user generated query text earlier this year. I started down a path to manually process it, but it quickly became overwhelming. I took a couple days to get up the speed on ANTLR and had an initial version of my grammar and processor running in a few days. Subsequent changes and adjustments to the requirements would have killed any custom version, but required relatively little effort to adjust once I had the ANTLR grammars up and running.
今年早些时候,我有一个项目必须处理一些用户生成的查询文本。我开始手动处理它,但很快就变得势不可挡。我花了几天时间来提高 ANTLR 的速度,并在几天内运行了我的语法和处理器的初始版本。对需求的后续更改和调整会杀死任何自定义版本,但是一旦我启动并运行了 ANTLR 语法,就需要进行相对较少的调整。
Good luck!
祝你好运!
回答by Michael Borgwardt
If you call that "natural language", you're deluding yourself. It's still a programming language, just one that tries to mimic natural language - and I suspect that it will fail once you get into implementation details. In order to make in unambiguous, you'll have to put restrictions on the syntax that will confuse the users who've been led to think that they're writing "English".
如果你称之为“自然语言”,那你就是在自欺欺人。它仍然是一种编程语言,只是一种试图模仿自然语言的语言——我怀疑一旦你进入实现细节它就会失败。为了明确无误,您必须对语法进行限制,这会使那些被引导认为他们在写“英语”的用户感到困惑。
The advantage of a DSL is (or should be, at any rate) is that it's simple and clear, yet powerful in regard to the problem domain. Mimicking a natural language is a secondary concern, and may in fact be counter-productive to those primary goals.
DSL 的优点是(或者无论如何应该是)它简单明了,但在问题域方面却很强大。模仿自然语言是次要的问题,实际上可能会适得其反。
If someone is too stupid or lacks the ability for formally rigorous thinking that's required for programming, then a programming language that mimicks a natural one will NOT magically turn them into a programmer.
如果某人太愚蠢或缺乏编程所需的形式严谨的思维能力,那么模仿自然语言的编程语言不会神奇地将他们变成程序员。
When COBOL was invented, some people seriously believed that within 10 years there would be zero demand for professional programmers, since COBOL was "like English", and anyone who needed software could write it himself. And we all know how that's been working out.
COBOL刚发明的时候,有人认真地认为10年之内对专业程序员的需求会为零,因为COBOL“就像英文一样”,任何需要软件的人都可以自己编写。我们都知道这是如何解决的。
回答by Fabian Steeg
回答by OscarRyz
The first time I heard of DSL was from Jetbrains, the creator of IntellJ Idea.
我第一次听说 DSL 是来自 IntellJ Idea 的创造者 Jetbrains。
They have this tool: MPS ( Meta Programming System )
他们有这个工具:MPS(元编程系统)
回答by Alex Miller
You might find this multi-part blog series I did on using Antlr to be useful as a starting point. It uses Antlr 2, so some stuff will be different for Antlr 3:
您可能会发现我使用 Antlr 所做的这个由多部分组成的博客系列作为起点很有用。它使用 Antlr 2,因此 Antlr 3 的某些内容会有所不同:
http://tech.puredanger.com/2007/01/13/implementing-a-scripting-language-with-antlr-part-1-lexer/
http://tech.puredanger.com/2007/01/13/implementing-a-scripting-language-with-antlr-part-1-lexer/
Mark Volkman's presentations/articles on Antlr are quite helpful as well:
Mark Volkman 关于 Antlr 的演讲/文章也很有帮助:
http://www.ociweb.com/mark/programming/ANTLR3.html
http://www.ociweb.com/mark/programming/ANTLR3.html
I will second the suggestion about the Definitive ANTLR book, which is also excellent.
我将支持有关 Definitive ANTLR 书的建议,这本书也很棒。
回答by Alex Miller
"One quite clear application of that, at least for me, would be to allow application testers create "testing scripts" in natural language and then parse the sentences into classes that uses JUnit to check for app behaviors"
“至少对我而言,一个非常明确的应用是允许应用程序测试人员以自然语言创建“测试脚本”,然后将句子解析为使用 JUnit 检查应用程序行为的类”
What you are talking about here sounds exactly like the tool, FitNesse. Exactly as you describe, clients write acceptance tests "scripts" in some kind of language that makese sense to them, and programmers build systems that make the tests pass. Even the implementation you talk about is pretty much exactly how FitNesse works - the vocabulary used in the scripts are concatenated to form function names etc, so that the FitNesse framework knows what function to call.
您在这里谈论的内容听起来与 FitNesse 工具完全一样。正如您所描述的,客户以某种对他们有意义的语言编写验收测试“脚本”,而程序员则构建使测试通过的系统。甚至您谈论的实现也几乎完全是 FitNesse 的工作方式 - 脚本中使用的词汇被连接起来形成函数名称等,以便 FitNesse 框架知道要调用什么函数。
Anyway, check it out :)
无论如何,检查一下:)

