【问题标题】:What would the best tool to create a natural DSL in Java? [closed]在 Java 中创建自然 DSL 的最佳工具是什么? [关闭]
【发布时间】:2008-09-27 19:56:12
【问题描述】:

几天前,我阅读了一篇博文 (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 这样的框架,那就更好了,我认为这可能会用锤子杀死苍蝇。

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

【问题讨论】:

  • 类似于 Glurk 的回答,因此作为评论:如果您寻找可执行的“自然”语言规范,您应该尝试 Cucumber (cukes.info)。与 JRuby(和 RSpec)一起,您可以将它用于基于 Java 的 BDD (behaviour-driven.org)。替代品包括 EasyB 和 JBehave。
  • 什么是 DSL?是相似语言的消歧吗?参见 corporavm.uni-koeln.de/vardial/sharedtask.html

标签: java dsl nlp parsing


【解决方案1】:

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

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

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

祝你好运!

【讨论】:

  • 乔,谢谢。我把那本书添加到我在亚马逊上的购物车几次。你认为基于注册的解析器创建动态语法树会很容易吗?库必须使用反射来提取类名、方法、(...)并为 ANTLR 创建语法树,对吧?
  • 可以直接在语法中插入Java(或者其他,ANTLR可以生成多种语言)。我用一种语法来解析我的 DSL,用另一种语法来遍历 AST 树,处理节点。由于这一切都在您的应用程序中运行,它可以轻松创建对象和调用方法。
  • 我花了几天的时间才把注意力集中在 ANTLR 上,从来没有上过词法分析器/解析器/编译课程。我很高兴我做到了,因为它将来一次又一次地有用。 Parr 编写了 ANTLR,所以这本书是一个很好的资源,也是对词法分析和解析的很好的介绍。
  • 乔,您的反馈非常好,我一定会买这本书。
  • 如果您访问 Pragmatic Bookshelf 网站 (pragprog.com/titles/tpantlr/the-definitive-antlr-reference),您可以以 45.75 + 运费获得这本书和 PDF 副本。祝你好运。您不会后悔为自己的技能选择新工具。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

    • +1,是的,公司实际上正在放弃 COBOL,这让我很生气。既然有很多便宜的说英语的人,为什么还要雇用昂贵的程序员?
    【解决方案4】:

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

    他们有这个工具:MPS ( Meta Programming System )

    【讨论】:

    • 你是说 DSL,不是 DLS?
    【解决方案5】:

    您可能会发现我所做的关于使用 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 书的建议,这本书也很棒。

    【讨论】:

      【解决方案6】:

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

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

      不管怎样,看看吧:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-06
        • 1970-01-01
        • 2010-12-13
        • 1970-01-01
        • 1970-01-01
        • 2010-09-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多