几天前,我读了一篇博客文章(http://ayende.com/Blog/archive/2008/09/08/Implementing-generic-natural-language-DSL.aspx),其中作者讨论了使用.NET的通用自然语言DSL解析器的想法。
在我看来,他的想法中很棒的部分是使用与句子相同的名称对文本进行解析和匹配。
举个例子,以下几行:
Create user user1 with email test@email.com 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
将使用“已知”对象的集合进行转换,这些对象将获取解析结果。一些示例对象(使用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;
}
}
因此,当处理第一句时,CreateUser类将是一个匹配(显然是因为它是“create user”的串联),并且,因为它在构造函数上采用了一个参数,所以解析器将“user1”作为用户参数。
之后,解析器将识别下一部分“with email”也与方法名称匹配,并且由于该方法采用参数,因此它会将“test@email.com”解析为电子邮件参数。
我想你现在明白了,对吗?至少对我来说,一个非常明确的应用是允许应用程序测试人员用自然语言创建“测试脚本”,然后将句子解析为使用JUnit检查应用程序行为的类。
我想听听有关使用Java编写此类解析器代码的工具或资源的想法,提示和意见。更好的是,如果我们可以避免使用复杂的词法分析器,或者像ANTLR这样的框架,我认为可能会使用锤子杀死苍蝇。
更重要的是,如果有人要为此开始一个开源项目,我肯定会感兴趣。
答案 0 :(得分:25)
考虑到lexing和解析的复杂性,我不知道我是否想要手动编写所有代码。 ANTLR并不难以拾取,我认为值得根据您的问题进行调查。如果您使用解析语法从输入构建和抽象语法树,那么它很漂亮很容易用树语法处理AST。树语法可以轻松处理您描述的过程。
你可以在许多地方找到ANTLR,包括Eclipse,Groovy和Grails。 The Definitive ANTLR Reference甚至可以非常直接地快速掌握基础速度。
我有一个项目,必须在今年早些时候处理一些用户生成的查询文本。我开始尝试手动处理它,但很快就变得势不可挡。我用了几天的时间来提高ANTLR的速度,并在几天内运行了我的语法和处理器的初始版本。对需求的后续更改和调整会导致任何自定义版本死亡,但是一旦我启动并运行ANTLR语法,就需要相对较少的调整工作。
祝你好运!答案 1 :(得分:10)
如果你称之为“自然语言”,那你就是在欺骗自己。它仍然是一种编程语言,只是一种试图模仿自然语言的语言 - 我怀疑它一旦你进入实现细节就会失败。为了明确说明,你必须对语法施加限制,这会限制那些被认为自己正在写“英语”的用户。
DSL的优势在于(或者应该是,无论如何),它在问题域方面简单明了,但功能强大。模仿自然语言是次要问题,实际上可能会对这些主要目标产生反作用。
如果有人太愚蠢或缺乏编程所需的正式严谨思考的能力,那么模仿自然的编程语言就不会让他们神奇地变成程序员。
当COBOL被发明时,有些人认为在10年内对专业程序员的需求为零,因为COBOL“喜欢英语”,任何需要软件的人都可以自己编写。我们都知道这是如何运作的。
答案 2 :(得分:9)
您可能需要考虑Xtext,它在内部使用ANTLR并执行一些很好的操作,例如为您的DSL自动生成编辑器。
答案 3 :(得分:4)
我第一次听说DSL来自Jetbrains,它是IntelliJ Idea的创造者。他们有这个工具:MPS ( Meta Programming System )
答案 4 :(得分:1)
你可能会发现我使用Antlr做的这个多部分博客系列作为起点非常有用。它使用Antlr 2,因此Antlr 3的一些东西会有所不同:
http://tech.puredanger.com/2007/01/13/implementing-a-scripting-language-with-antlr-part-1-lexer/
Mark Volkman关于Antlr的演讲/文章也非常有用:
http://www.ociweb.com/mark/programming/ANTLR3.html
我将提出关于最终ANTLR书的建议,这本书也非常出色。
答案 5 :(得分:0)
“至少对我而言,一个非常明确的应用是允许应用程序测试人员用自然语言创建”测试脚本“,然后将句子解析为使用JUnit检查应用程序行为的类”
你在这里所说的听起来就像工具FitNesse。 正如您所描述的那样,客户端以某种语言编写接受测试“脚本”,这对他们来说是有意义的,程序员构建了使测试通过的系统。甚至您所讨论的实现也几乎都是FitNesse的工作方式 - 脚本中使用的词汇表连接起来形成函数名称等,以便FitNesse框架知道要调用的函数。
无论如何,请查看:)