18

我只是对特定领域的语言感到好奇。我在文章中看到过好几次,似乎可以在保险之外使用它们或银行数据定义问题。

所以我来 SO 有一些具体的意见。

你用过DSL吗?写一个。如果是,那是什么感觉?

你认为你的一个项目使用 DSL 会更好(更高效、更可维护……)吗?

编辑:我很抱歉把它放在后面,但我的意思是你自己写的一个特定的 DSL。它不包括 Tex、HTML、Make、SQL。事实上,问题更多的是:“编写 DSL”

4

12 回答 12

8

SQL 是Michael Dorfman给出的一个很好的例子。我广泛使用的其他方法是:

  • UIL - GUI 构建
  • Make - 程序构建和安装
  • regexp - 字符串模式匹配
  • lex 和 yacc - 词法分析器和编译器创建

至于效果如何,我认为这取决于语言和领域。UIL 非常适合指定 GUI。如果您在内联 Motif 代码中执行相同的操作,那么 UIL 编译器捕获的 GUI 规范错误对于 C 或 Ada 编译器来说就像是完全可编译的代码。这会导致大量时间浪费在调试上。另外,它在使用 Motif API 调用的通用代码中看起来更丑陋。

Make 真的可以成为一场噩梦,但是没有很多工具可以做它所做的事情,我怀疑它们都有同样的问题。

非常简单的任务不需要正则表达式,而对于真正复杂的任务来说则是一场噩梦。对于中间的人来说,它们是一个很好的工具。

Lex 和 yacc 会很有帮助。但是,知道自己在做什么的人可以手动创建解析器和词法分析器,工作量大致相同。

于 2009-07-10T13:44:29.380 回答
8

我想说在可读性很强的 API 作为弱形式的 DSL(有些人称之为流式接口)、作为介于两者之间的内部 DSL 和另一端的完整语法定义的外部 DSL 之间存在相当大的连续性。

最弱的形式是我总是试图实现的(即使 API 尽可能接近问题域)。如果非程序员将使用该软件,例如输入数据,则连续统一体另一端的 DSL 非常有意义。

对于像Xtext这样的框架,即使是完整的外部 DSL,包括支持语法着色和错误检查的编辑器,也比最初看起来更容易实现。

于 2009-07-10T14:15:29.933 回答
7

你的问题很及时。我最近使用Antlr工具编写了一个 DSL 。Antlr 是一个解析器/词法分析器生成器。
它允许轻松构建 DSL(以及许多其他东西),并且当与StringTemplate(由同一个人编写)结合使用时,在代码生成中变得非常强大。它还可以针对多种语言。我们的解析器和词法分析器使用 C#(目标之一),即使默认是 Java。

Antlr 的众多好处之一是描述性错误消息和 IDE/调试器 (AntlrWorks),它允许您逐步了解语法并直观地查看 AST 树。

John Saunders 在下面建议使用内置的 Visual Studio DSL 工具包。最终,我发现这些工具远非限制性的。需要一个 GUI,而没有任何能力轻松描述底层文本语法,这似乎不足以满足我的需求。

除了 DSL 解析器/词法分析器,我还编写了一个 Visual Studio 语言服务,以提供智能感知、错误突出显示、代码完成和模板项/项目。

即使您不实现附加功能,DSL 也可以简化重复性工作。我的 DSL 专门针对CSLA 框架,通过所有管道轻松生成业务对象,让开发人员只需担心业务逻辑。

这是 DSL 的一个小例子:

datadef Object1Datadef
{

   tables
   {
      MyTable:PK[MyTableID], column1, column2;
   }

}

root MyObject
{
    datadef Object1Datadef;

    read "all";
    write "admin", "superusers";

    int _Myvariable;    

}

如果您的 DSL 允许您更快、更轻松地描述您的域并提高生产力,那么它是值得的。

于 2009-07-10T15:17:57.820 回答
6

我认为我们大多数人最常使用的 DSL 是 SQL,一种用于数据操作和提取的小语言。

于 2009-07-10T13:34:56.787 回答
3

DSL 的两个近期用途:

  1. 使用构造库 - 它基本上定义了用于描述数据的二进制结构(例如文件格式)和协议的 DSL。
  2. 实现基于 Python 的 DSL 来验证硬件。该 DSL 将编写测试所需的所有基础设施布置为可以使用底层 DSL 组件的“场景函数”。
于 2009-07-10T12:29:29.500 回答
3

我是在NUnit 2.0 版及更高版本上工作了几年的人之一。它是使用 C# 属性编写的用于描述单元测试的 DSL。这不是 DSL 最明显的例子,但我已经开始将其视为一个。我用 ANTLR 甚至 MGrammar 写了一些其他的。体验往往是一样的。一旦你把它展示给别人,他们就会想做一堆你从未想过的事情。这是一件好事,但您必须准备好继续前进并添加功能。

我现在养成了经常思考和编写 DSL 的习惯。我使用的当前对象关系映射器是 dsl。它不是一门新语言。它是纯 C#,但考虑到域的语言,并且域不仅仅是业务域,我们创建了一种迷你语言来映射对象。对 DSL 的思考改变了我们构建 API 和框架的方法。

于 2009-10-05T09:07:15.180 回答
2

实际上,您几乎每天都在使用 DSL,但您并不自知…… HTML、make、XML、latex 和许多配置语言……

我喜欢有一个声明性的 DSL 来生成一堆东西……感觉很好……

DSL 的影响是什么是一个有趣但真的很难评估...做好它应该做的工作,它会感觉很好......

但是,如果您在不了解社区的情况下设计 DSL,或者如果他们需要不断与语言的限制作斗争(DSL 仍然可以是图灵完备的......),那将会受到伤害......

于 2009-07-10T14:48:41.720 回答
2

根据我的经验,任何软件工程组织都会创建 DSL 来应对重复出现的问题和编写过多的模板代码。我个人经验的简短摘录:

  • 编译器自下而上重写系统生成器
  • 汇编生成器
  • 对象代码生成器(实现为具有运算符重载的 C++ 库)
  • CPU模拟器生成器
  • 模拟器设备模型生成器
  • 交互式工具的命令行语言

另请注意,如果仔细观察,许多文件格式都可以被视为 DSL。

不久前, Mark Shapiro 在 ACM Queue 中也有一篇关于这种现象的好文章。

另一个例子是用户最终在不适合它的东西中编写大程序的方式......比如使用旧的“SNIFF”调试器脚本语言的测试台。

于 2009-10-05T07:23:59.347 回答
2

这可能是一个老问题,但标题中的问题(而不是正文中的问题)并没有真正得到任何人的回答:

有两个(双重)情况下编写 DSL 是有意义的:

  • 当问题域被很好地理解并且具有预先存在的名词(对象)、动词(动作、组合词等)和形容词(属性、修饰语)词汇时。
  • 当解决方案域被很好地理解并且......

正则表达式是第一个很好的例子,而汇编器生成器是第二个。剩下的就是通用编程语言:当问题域和解决方案域都没有那么好理解时,因此必须使用通用工具。

于 2010-06-25T14:26:07.117 回答
0

BNF 作为解析器生成器的 DSL 怎么样?

于 2009-07-10T13:48:07.330 回答
0

使用 Visual Studio DSL Toolkit创建的 DSL可用于从 DSL 定义的域模型实例生成任何基于文本的工件。当然,当时在 Visual Studio 内部,如果文本工件有编译器或其他处理器,那么它可以自动运行。

一些例子是

  • NORMA,一种用于概念领域建模的 DSL,基于对象角色建模表示法 (ORM2)
  • Web 服务软件工厂,它使用三个 DSL 来对 Web 服务进行建模
  • 配置部分设计器- 用于定义 XML 配置文件的模式并生成类以从中公开数据。

当然,您也可以创建自己的。

于 2009-07-10T14:00:01.950 回答
0

我还是个学生,但我真的很着迷于精神

我在我的“编程语言”课程中使用了一点。这就是它的工作原理,基本上你正在编写 EBNF。

替代文字 http://img6.imageshack.us/img6/1461/reala.png

在C++中变成这个;)

替代文字 http://img6.imageshack.us/img6/8809/dsl.png

于 2009-07-10T22:39:21.553 回答