我只是对特定领域的语言感到好奇。我在文章中看到过好几次,似乎可以在保险之外使用它们或银行数据定义问题。
所以我来 SO 有一些具体的意见。
你用过DSL吗?写一个。如果是,那是什么感觉?
你认为你的一个项目使用 DSL 会更好(更高效、更可维护……)吗?
编辑:我很抱歉把它放在后面,但我的意思是你自己写的一个特定的 DSL。它不包括 Tex、HTML、Make、SQL。事实上,问题更多的是:“编写 DSL”
我只是对特定领域的语言感到好奇。我在文章中看到过好几次,似乎可以在保险之外使用它们或银行数据定义问题。
所以我来 SO 有一些具体的意见。
你用过DSL吗?写一个。如果是,那是什么感觉?
你认为你的一个项目使用 DSL 会更好(更高效、更可维护……)吗?
编辑:我很抱歉把它放在后面,但我的意思是你自己写的一个特定的 DSL。它不包括 Tex、HTML、Make、SQL。事实上,问题更多的是:“编写 DSL”
SQL 是Michael Dorfman给出的一个很好的例子。我广泛使用的其他方法是:
至于效果如何,我认为这取决于语言和领域。UIL 非常适合指定 GUI。如果您在内联 Motif 代码中执行相同的操作,那么 UIL 编译器捕获的 GUI 规范错误对于 C 或 Ada 编译器来说就像是完全可编译的代码。这会导致大量时间浪费在调试上。另外,它在使用 Motif API 调用的通用代码中看起来更丑陋。
Make 真的可以成为一场噩梦,但是没有很多工具可以做它所做的事情,我怀疑它们都有同样的问题。
非常简单的任务不需要正则表达式,而对于真正复杂的任务来说则是一场噩梦。对于中间的人来说,它们是一个很好的工具。
Lex 和 yacc 会很有帮助。但是,知道自己在做什么的人可以手动创建解析器和词法分析器,工作量大致相同。
我想说在可读性很强的 API 作为弱形式的 DSL(有些人称之为流式接口)、作为介于两者之间的内部 DSL 和另一端的完整语法定义的外部 DSL 之间存在相当大的连续性。
最弱的形式是我总是试图实现的(即使 API 尽可能接近问题域)。如果非程序员将使用该软件,例如输入数据,则连续统一体另一端的 DSL 非常有意义。
对于像Xtext这样的框架,即使是完整的外部 DSL,包括支持语法着色和错误检查的编辑器,也比最初看起来更容易实现。
你的问题很及时。我最近使用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 允许您更快、更轻松地描述您的域并提高生产力,那么它是值得的。
我认为我们大多数人最常使用的 DSL 是 SQL,一种用于数据操作和提取的小语言。
DSL 的两个近期用途:
我是在NUnit 2.0 版及更高版本上工作了几年的人之一。它是使用 C# 属性编写的用于描述单元测试的 DSL。这不是 DSL 最明显的例子,但我已经开始将其视为一个。我用 ANTLR 甚至 MGrammar 写了一些其他的。体验往往是一样的。一旦你把它展示给别人,他们就会想做一堆你从未想过的事情。这是一件好事,但您必须准备好继续前进并添加功能。
我现在养成了经常思考和编写 DSL 的习惯。我使用的当前对象关系映射器是 dsl。它不是一门新语言。它是纯 C#,但考虑到域的语言,并且域不仅仅是业务域,我们创建了一种迷你语言来映射对象。对 DSL 的思考改变了我们构建 API 和框架的方法。
实际上,您几乎每天都在使用 DSL,但您并不自知…… HTML、make、XML、latex 和许多配置语言……
我喜欢有一个声明性的 DSL 来生成一堆东西……感觉很好……
DSL 的影响是什么是一个有趣但真的很难评估...做好它应该做的工作,它会感觉很好......
但是,如果您在不了解社区的情况下设计 DSL,或者如果他们需要不断与语言的限制作斗争(DSL 仍然可以是图灵完备的......),那将会受到伤害......
根据我的经验,任何软件工程组织都会创建 DSL 来应对重复出现的问题和编写过多的模板代码。我个人经验的简短摘录:
另请注意,如果仔细观察,许多文件格式都可以被视为 DSL。
不久前, Mark Shapiro 在 ACM Queue 中也有一篇关于这种现象的好文章。
另一个例子是用户最终在不适合它的东西中编写大程序的方式......比如使用旧的“SNIFF”调试器脚本语言的测试台。
这可能是一个老问题,但标题中的问题(而不是正文中的问题)并没有真正得到任何人的回答:
有两个(双重)情况下编写 DSL 是有意义的:
正则表达式是第一个很好的例子,而汇编器生成器是第二个。剩下的就是通用编程语言:当问题域和解决方案域都没有那么好理解时,因此必须使用通用工具。
BNF 作为解析器生成器的 DSL 怎么样?
使用 Visual Studio DSL Toolkit创建的 DSL可用于从 DSL 定义的域模型实例生成任何基于文本的工件。当然,当时在 Visual Studio 内部,如果文本工件有编译器或其他处理器,那么它可以自动运行。
一些例子是
当然,您也可以创建自己的。
我还是个学生,但我真的很着迷于精神
我在我的“编程语言”课程中使用了一点。这就是它的工作原理,基本上你正在编写 EBNF。
替代文字 http://img6.imageshack.us/img6/1461/reala.png
在C++中变成这个;)