题
您会推荐哪种技术来为以下应用程序创建 DSL: .NET 的业务规则和验证应用程序块?为什么?
框架的架构是通过产品建立和验证测试的。我只想创建一个 .NET 处理器来将人类可读的规则转换为已编译的规则实现。
我知道的选项是:
- 使用编译器管道 .NET嘘声
- 使用 F# 附带的解析器构建器 - FsLex 和 FsYacc
不幸的是,考虑到 DSL 语法(将会发展),这些方法都没有提供任何东西来构建或多或少友好的 IDE 来编辑 DSL。
有什么想法或提示吗?
解决方案
微软下一代应用开发平台,代号 奥斯陆
使人们更容易以对他们正在处理的问题领域有意义的方式写下内容
Oslo 似乎由名为“Quadrant”的可视化设计工具、名为“M”的建模语言以及存储规则的“Oslo”存储库(SQL Server 数据库)组成。
因此,如果我理解正确,您可以在 M 中定义建模语言,使用 Quadrant 使用您自己的建模语言定义和编辑验证规则,并编写一个利用 Oslo 存储库的应用程序,生成您的业务规则和验证应用程序.NET 的块。
其他提示
业务规则的图形语言不是一个好主意。我会避免它业务规则中有很多 if 检查和循环,这些检查和循环不太直观。
使用文本语言来描述业务规则会更好。
要获得出色的代码编辑用户体验,您需要:
- 具有良好错误恢复能力的解析器
- 进行增量重新编译的能力
良好的错误恢复使您能够从语法不完整的结构中有效地确定程序员的意图。这对于实现智能至关重要。
进行增量重新编译的能力使您能够进行有效的后台编译以响应用户编辑。
获得良好错误恢复的最简单方法是手动编写解析器。这样,您就可以使用任意数量的前瞻或算法规则来确定出现语法错误时该怎么做。
当您使用解析器生成器创建解析器时,您在处理语法错误时失去了很多灵活性。这种灵活性决定了良好的智能体验和蹩脚的智能体验之间的区别。因此,我建议您使用递归下降手工编写它。
实施高效的重新编译要求您能够:1) 正确地将语义分析分为几个阶段(对于 C# 之类的东西,这将是:首先构造命名空间和类型符号,然后解析 using 语句,然后解析基类等)。2)构建相位感知依赖关系图的能力 3) 用于处理依赖关系图的算法,并使其部分内容无效以响应用户编辑
对于成熟的编程语言,实现重新编译可能会变得非常棘手。在您的情况下,因为您正在描述业务规则,所以它对您来说可能要简单得多(或者如果编译足够快,您甚至可能不需要它)。
因此,我将从解析器开始,然后在其之上构建智能。
如果你可以避免 VS 集成,我会的。集成到 VS 需要大量的管道,并且互操作可能会引起头痛。有几家公司出售 Windows 窗体编辑器控件,您可以将解析器连接到这些控件。这比 VS 更容易集成。
另一个可能有趣的替代方案是使用 F# 引号。
引用允许您将程序的一部分视为数据,因此您可以获取 AST,对其进行分析并将其翻译为其他语言或以某种非标准方式执行。加上 F# 的灵活性,您应该能够表达许多内容,因此您必须开发一个内部 F# DSL/组合器库来描述规则,并开发一个 F# 引用的翻译器/解释器来运行它们。
不确定业务规则是什么样子,但你可以写这样的东西:
let rule = <@
if (exists customer having validEmail) then success
else require whatever
@>
我在我的博客上写了关于这个主题的介绍。不幸的是,F# CTP 发生了一些重大变化,我还没有更新源代码,但它应该让您很好地了解这种方法的可能性和局限性。
- CodePlex 上的 F# 引用示例 - 托马斯P.Net
F# 单元测试框架是 DSL 的一个很好的例子:
- 发布 FsTest - F# 测试 DSL ——马修·波德维索基
[编辑]只是为了澄清为什么我认为这可能是一个好方法:
- 如果您使用 Visual Studio 编辑 DSL(并且可以使用免费安装了 F# 的 Shell 版本),您将免费获得非常好的编辑体验。不仅是语法高亮显示,还有 IntelliSense,它会建议可能的构造,并且还有后台类型检查,可充当 DSL 的“语法”检查器。
- 与其他方法相比,这可能是最容易实现的方法之一。
- 唯一的限制是您受到 F# 语法的限制。然而,设计自己的语言确实很困难,所以这可能并没有那么糟糕。特别是考虑到 F# 的灵活性。
[/编辑]
希望这可以帮助!
用于构建 DSL 接缝的标准工具是 ANTLR - 它是一个强大的词法分析器/解析器生成器,具有许多用于编译器输出的目标语言。它有 C#、Java、C/C++、Python 等后端。(参见 代码生成目标 列表),并让您可以轻松地将自定义代码注入目标语言的编译器中。
还有一个非常强大的 IDE (ANTLRWorks) 和大量文档。(查看 防御性 ANTLR 参考 来自 ANTLR 的作者 Terrence Parr)有关其他人使用它的参考资料,请参阅 感言 页。
您仍然需要自己完成 IDE 的大部分工作,但考虑到您将从 ANTLR 获得的强大的编译器框架,这应该容易得多。此处发布的大多数解决方案都应该是这种情况......
我目前正在使用用 ANTLR 编写的编译器来预处理我们自己的 DSL 到 C/C++ 的输出,对此我非常满意。广告已经说够了,您应该亲自尝试一下:)玩得开心!
捷脑公司 元编程系统
您可以为任何新语言定义自定义语言编辑器和其他约束,以便使用这些 DSL 变得非常简单。不熟悉传统编程的领域专家可以使用特定领域的术语,使用特定领域的语言轻松地在 MPS 中工作。
Boo + OMeta = Boo.OMeta.Parser
目前解析器正在开发中,但它已经可以用于创建复杂的外部 DSL。OMeta 是一个功能强大的工具,它使程序员能够轻松实现词法分析器和解析器。Boo 的可扩展编译器管道架构允许用 Boo.OMeta.Parser 替换标准 Boo.Parser。它可以用来用几乎任何类型的语法来扩展 Boo 语法。例子可以找到 这里.
我的项目 元# 正在努力解决这个问题。
如果您想创建一个编辑 DSL 的友好 IDE,请使 IDE 完全图形化,并编译为 .NET 对象(或使用 IronPython 等语言作为粘合语言)。
如果规则足够简单,您可以以图形方式实现整个规则结构。如果规则足够复杂,“人类可读性”就成为一个不可能的目标。
无论哪种方式,如果创建中间代码的一组 .NET 类或 IronPython 对象不够“人类可读”,那么您很可能需要比语法更具有虚拟性的东西。
也就是说,如果您只想创建一种简单的语言供程序员用来创建业务规则,请随意使用上述任何语言,并使语法足够简单,不需要 Visual Studio 的 IDE。