15

几天前,我阅读了一篇博客文章 ( http://ayende.com/Blog/archive/2008/09/08/Implementing-generic-natural-language-DSL.aspx ),其中作者讨论了使用 .NET 的通用自然语言 DSL 解析器。

在我看来,他的想法的绝妙之处在于,文本被解析并与使用与句子同名的类进行匹配。

以下面几行为例:

使用电子邮件 test@email.com 和密码 test 创建用户 user1
登录用户 1
将 user1 带到 T 恤分类
让 user1 将商品 Flower T-Shirt 添加到购物车
带 user1 结帐

将使用“已知”对象的集合进行转换,该集合采用解析结果。一些示例对象将是(在我的示例中使用 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 这样的框架,我认为这可能会用锤子杀死苍蝇,那就更好了。

不仅如此,如果有人愿意为此启动一个开源项目,我肯定会感兴趣。

4

6 回答 6

25

考虑到词法分析和解析的复杂性,我不知道是否要手动编写所有代码。 ANTLR并不难拾取,我认为根据您的问题值得研究。 如果您使用解析语法从输入构建和抽象语法树,那么使用树语法处理该 AST 非常容易。树语法可以轻松处理执行您描述的过程。

您会在很多地方找到 ANTLR,包括 Eclipse、Groovy 和 Grails。 Definitive ANTLR Reference甚至可以相当简单地快速掌握基础知识。

今年早些时候,我有一个项目必须处理一些用户生成的查询文本。我开始手动处理它,但很快就变得不堪重负。我花了几天时间来加快 ANTLR 的速度,并在几天内运行了我的语法和处理器的初始版本。对需求的后续更改和调整会杀死任何自定义版本,但是一旦我启动并运行了 ANTLR 语法,就需要相对较少的精力进行调整。

祝你好运!

于 2008-09-27T20:17:09.093 回答
10

您可能需要考虑Xtext,它在内部使用 ANTLR 并做了一些不错的事情,例如为您的 DSL 自动生成编辑器。

于 2008-09-28T00:31:06.097 回答
10

如果您称其为“自然语言”,那您就是在自欺欺人。它仍然是一种编程语言,只是一种试图模仿自然语言的语言——我怀疑一旦你进入实现细节它就会失败。为了明确起见,您必须对语法进行限制,这会使那些被引导认为他们正在写“英语”的用户感到困惑。

DSL 的优点是(或者无论如何应该是)它简单明了,但在问题域方面却很强大。模仿自然语言是次要的问题,实际上可能会适得其反。

如果某人太愚蠢或缺乏编程所需的形式严谨的思维能力,那么模仿自然语言的编程语言不会神奇地将他们变成程序员。

在 COBOL 发明的时候,有人认真地认为,10 年内对专业程序员的需求将为零,因为 COBOL “像英语一样”,任何需要软件的人都可以自己编写。我们都知道这是怎么回事。

于 2009-03-25T11:07:05.993 回答
4

我第一次听说 DSL 是来自 IntellJ Idea 的创建者 Jetbrains。

他们有这个工具:MPS(元编程系统)

于 2009-01-28T00:26:47.943 回答
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

我会支持关于 Definitive ANTLR 书的建议,这本书也很棒。

于 2008-09-28T01:10:27.657 回答
0

“至少对我来说,一个非常明确的应用是允许应用程序测试人员用自然语言创建“测试脚本”,然后将句子解析为使用 JUnit 来检查应用程序行为的类”

您在这里谈论的内容听起来与工具 FitNesse 完全一样。正如您所描述的那样,客户使用某种对他们有意义的语言编写验收测试“脚本”,而程序员则构建使测试通过的系统。即使您谈论的实现也几乎完全是 FitNesse 的工作原理 - 脚本中使用的词汇被连接起来形成函数名称等,因此 FitNesse 框架知道要调用什么函数。

无论如何,检查一下:)

于 2009-03-25T10:46:17.650 回答