【问题标题】:What technology to use in creating DSL for rules engine?在为规则引擎创建 DSL 时使用什么技术?
【发布时间】:2010-10-07 10:51:27
【问题描述】:

您会推荐什么技术来为Business Rules and Validation Application Block for .NET 创建 DSL?为什么?

框架的架构由产品建立和验证测试。我只想创建一个 .NET 处理器来将人类可读的规则转换为已编译的规则实现。

我知道的选项是:

不幸的是,考虑到 DSL 语法(会不断发展),这些方法都没有提供任何东西来构建或多或少友好的 IDE 来编辑 DSL。

有什么想法或提示吗?

【问题讨论】:

  • 主题中的“to”太多了?
  • 谢谢,错过了。

标签: .net f# dsl rules boo


【解决方案1】:

微软下一代应用开发平台,代号Oslo (now Delve)

使人们更容易以对他们所从事的问题领域有意义的方式写下来

Oslo 似乎包含一个名为“Quadrant”的可视化设计工具、一种名为“M”的建模语言,以及存储规则的“Oslo”存储库(一个 SQL Server 数据库)。

因此,如果我没看错的话,您可以在 M 中定义一种建模语言,使用 Quadrant 使用您自己的建模语言定义和编辑您的验证规则,然后编写一个使用 Oslo 存储库的应用程序,生成您的业务规则和 .NET 的验证应用程序块。

【讨论】:

  • 我刚刚使用它来实现一个简单的 DSL,虽然这些位仍然有点原始,但它看起来确实很有希望,特别是与智能板集成。
  • 我一直在修补奥斯陆——这让我大开眼界。
  • 哦,是的! --larsw-from-oslo
  • 哦不——微软杀了奥斯陆吗?无论如何,给定的链接已经死了……而且搜索它似乎只会在实际的奥斯陆找到 MS 工作。还是名字变了?那确实是“代号”。
  • 尽管有一篇文章,但我不清楚 Delve 是否与您所说的工具相同 - 它似乎不是程序员建模工具。无论如何,它似乎是going away
【解决方案2】:

另一个可能有趣的替代方法是使用 F# 引号。

引用允许您将程序的一部分视为数据,因此您可以获取 AST,对其进行分析并将其翻译成其他语言或以某种非标准方式执行它。再加上 F# 的灵活性,您应该能够表达很多东西,因此您必须开发一个内部 F# DSL/combinator 库来描述规则,并开发一个 F# 引用的翻译器/解释器来运行它们。

不确定商务规则的外观,但您可以编写如下内容:

let rule = <@
  if (exists customer having validEmail) then success
  else require whatever 
@>

我在我的博客上写了一篇关于这个主题的介绍。不幸的是,F# CTP 发生了一些重大变化,我还没有更新源代码,但它应该能让您很好地了解这种方法的可能性和局限性。

DSL 的一个很好的例子是 F# 单元测试框架:

[编辑] 只是为了澄清为什么我认为这可能是一个好方法:

  • 如果您使用 Visual Studio 编辑 DSL(并且您可以使用免费安装 F# 的 Shell 版本),您将免费获得非常好的编辑体验。不仅是语法高亮,还有 IntelliSense,它会建议可能的结构,还有一个背景类型检查,作为 DSL 的“语法”检查器。
  • 与其他方法相比,这可能是最容易实施的方法之一。
  • 唯一的限制是您受 F# 语法的限制。但是,设计自己的语言确实很困难,所以这可能一点也不坏。尤其是考虑到 F# 的灵活性。

[/编辑]

希望这会有所帮助!

【讨论】:

    【解决方案3】:

    业务规则的图形语言不是一个好主意。我会避免它 业务规则中有很多 if 检查和循环,它们不能很好地可视化。

    使用文本语言来描述业务规则会更好。

    要获得出色的编辑代码用户体验,您需要:

    1. 具有良好错误恢复能力的解析器
    2. 增量重新编译的能力

    良好的错误恢复可以让您从语法不完整的结构中有效地确定程序员的意图。这对于实现智能至关重要。

    进行增量重新编译的能力使您能够进行有效的后台编译以响应用户编辑。

    获得良好错误恢复的最简单方法是手动编写解析器。这样,您可以使用任意数量的前瞻或算法规则来确定在出现语法错误时该怎么做。

    当您使用解析器生成器创建解析器时,您在处理语法错误方面失去了很多灵活性。这种灵活性决定了良好的智能体验和糟糕的智能体验。所以,我建议你使用递归下降手工编写它。

    实施有效的重新编译要求您能够: 1) 正确地将语义分析分解为多个阶段(对于 C# 之类的东西,这将是:首先构造名称空间和类型符号,然后解析 using 语句,然后解析基类等)。 2)构建相位感知依赖图的能力 3) 处理依赖图的算法,并根据用户编辑使其部分无效

    对于成熟的编程语言,实现重新编译可能会非常棘手。在您的情况下,因为您正在描述业务规则,所以它可能对您来说更简单(或者如果编译速度足够快,您甚至可能不需要它)。

    所以,我将从解析器开始,然后在它之上构建智能。

    如果您可以避免 VS 集成,我会的。集成到 VS 需要大量的管道,并且互操作可能会引起头痛。有几家公司出售您连接解析器的 Windows 窗体编辑器控件。这比 VS 更容易集成。

    【讨论】:

    • 循环并不像向非程序员解释那样难以图形化。我用大量循环的图形语言编写过,它们并不像你说的那么糟糕。例如,Envox CDP。对于非编码人员,解决意味着没有语法错误。
    • 如果有人无法理解这一点:foreach (customer in CustomerList) { CalculateFicoScore(customer); } 他们将如何理解它的图形表示。循环的难点在于概念,而不是它的显示方式。
    • 在使用解析器生成器时,错误恢复的大部分困难来自于 LR 和 LALR 解析器处理不佳的歧义(包括移位归约和归约归约冲突)。 GLR 算法(MS Oslo 使用的)以自然的方式解决了大部分问题。
    • scott:你可以用 F# 写得很好:customers |> map CalculateFicoScore
    【解决方案4】:

    我会使用 Boo,我认为它是目前最灵活的 DSL 创建工具之一。有一个关于这个主题的very good book。 Ayende's 和 Rodrigo's 博客也是很好的灵感来源。

    关于IDE,你可以扩展SharpDevelop,看看this。

    【讨论】:

      【解决方案5】:

      构建 DSL 接缝的标准工具是 ANTLR - 它是一个强大的词法分析器/解析器生成器,具有许多用于编译器输出的目标语言。它具有 C#、Java、C/C++、Python 等的后端(参见code generation targets 列表),让您可以轻松地将自定义代码以目标语言注入编译器。

      还有一个非常强大的 IDE (ANTLRWorks) 和大量文档。 (查看来自 ANTLR 的作者 Terrence Parr 的 The Defenitive ANTLR Reference)有关其他人使用它的参考资料,请参阅 Testimonlals 页面。

      您仍然需要自己完成 IDE 的大部分工作,但考虑到您将从 ANTLR 获得的强大的编译器框架,这应该会容易得多。此处发布的大多数解决方案都应该是这种情况...

      我目前正在使用用 ANTLR 编写的编译器将我们自己的 DSL 预处理为 C/C++ 输出,我对此非常满意。广告够了,你自己试试吧:)玩得开心!

      【讨论】:

        【解决方案6】:

        JetBrains Meta Programming System

        您可以为任何新语言定义自定义语言编辑器和其他约束,以便使用这些 DSL 变得非常简单。不熟悉传统编程的领域专家可以使用特定领域的术语使用特定领域的语言轻松地在 MPS 中工作。

        【讨论】:

          【解决方案7】:

          我是新手,但OMeta 似乎是开发 DSL 的理想工具。它周围似乎没有 IDE,但好消息是可以在 OMeta 中编写的“规则”非常易读。 (它处理左递归,这非常酷。)

          目前至少有 Javascript(对我来说非常令人兴奋)和 Python 中的 OMeta 实现,也许还有其他实现。至于 C#,Jeff Moser 正在开发一个,您可以在 his blog 上阅读并在 CodePlex 上查看。 祝你好运。

          【讨论】:

            【解决方案8】:

            Boo + OMeta = Boo.OMeta.Parser

            目前解析器正在开发中,但它已经可以用于创建复杂的外部 DSL。 OMeta 是一个强大的工具,它使程序员能够轻松地实现词法分析器和解析器。 Boo 的可扩展编译器管道架构允许用 Boo.OMeta.Parser 替换标准的 Boo.Parser。它可以用几乎任何一种语法来扩展 Boo 语法。 例子可以在here找到。

            【讨论】:

              【解决方案9】:

              我的项目meta# 正在尝试解决这个问题。

              【讨论】:

                【解决方案10】:

                如果您想创建一个编辑 DSL 的友好 IDE,使 IDE 完全图形化,并编译为 .NET 对象(或使用 IronPython 之类的东西作为胶水语言)。

                如果规则足够简单,您可以以图形方式实现整个规则结构。 如果规则足够复杂,“人类可读性”就成为不可能的目标。

                无论哪种方式,如果创建中间代码的一组 .NET 类或 IronPython 对象不够“人类可读”,那么很可能,您需要比语法更防伪的东西。

                也就是说,如果您只是想创建一种程序员可以用来创建业务规则的简单语言,请随意使用上述任何一种语言,并使语法足够简约,不需要 Visual Studio 的 IDE。

                【讨论】:

                  【解决方案11】:

                  Ruby 是一种用于创建 DSL 的出色语言。例如Rake 是一个用 Ruby 编写的构建脚本 DSL。

                  使用即将推出的IronRuby,可以编写直接调用您的 C# 代码的脚本。

                  Here'ssomearticles 在 Ruby 中编写 DSL。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2010-10-20
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2010-09-05
                    相关资源
                    最近更新 更多