2008-09-19 23 views
11

有什么工具可以帮助我构建真正的,诚实的外部DSL。不,我不是在谈论滥用Ruby,Boo,XML或其他现有的语言或语法,我的意思是一个真正的外部DSL - 我自己的语言是为了我自己的目的。构建有效的外部DSLs

我知道有几种语言工作台正在开发中,我听说过有关.NET的“反讽”之类的东西。当然,还有ANTLR,Lex/Yaac等,但恐怕这些对我所要做的事情来说太复杂了。

请谈谈您可能已经使用或听说过的DSL生成器工具以及您对它的帮助及其缺点的印象。

+0

注意:我不一定在这里寻找图灵的完整性。大多只是表达式语法来配置我的模型中的东西。 – chadmyers 2008-09-19 15:21:17

回答

9

我已经在Boo,Irony.NET和一个名为Grammatica的工具包中编写了DSL。你说一个解析器生成器太复杂了,但是你的判断可能过于仓促,事实上,一旦你学习了一条小小的学习曲线,它就很容易使用,并且开创了一个可能轻易覆盖的广阔世界。努力。我发现学习了为大多数解析器生成器编写语法所需的符号,这有点类似于学习正则表达式 - 你必须稍微弯曲一下头脑才能让它们进入,但奖励很重要。我的意见是这样的:如果你的目标语言足够简单,它可以被一个笨拙的可视化设计者处理,那么使用一个解析器生成器为它编写一个语法应该是相当容易的。

如果你的目标DSL足够复杂以至于你需要为编写语法打破汗水,那么虚拟的可视化工具无论如何不会切断芥末,最终你不得不学习写一个语法无论如何。

虽然我长期同意关于内部和外部的DSL。我在Boo中编写了一个内部DSL,并且必须修改我的DSL语法才能使其工作,并且它总是感觉像是黑客。使用Irony.NET或ANTLR的相同语法在实现更多灵活性时也同样容易。

我有一个blog post讨论一些选项。这篇文章主要围绕编写一个用于运行时表达式评估的DSL,但这些工具都是一样的。

我对Irony.NET的使用经验都很积极,并且有几种使用它的参考语言,这是一个很好的开始。如果你的语言很简单,启动和运行绝对不复杂。 CodeProject上还有一个名为TinyParser的库 - 这个库真的很有趣,因为它生成的解析器是纯粹的源代码,这意味着您的最终产品完全没有任何第三方引用。不过,我自己并没有使用它。

4

你应该真的退房Ragel。这是一个将状态机嵌入到常规源代码中的框架。 Ragel支持C,C++,Objective-C,D,Java和Ruby。

Ragel非常适合编写文件和协议解析器,以及跨越外部DSL的东西。主要是因为它允许你在状态转换等上执行任何类型的代码。

一些使用Ragel的着名项目是Mongrel,这是一个伟大的ruby web服务器。而基于ruby的html解析器Hpricot也受到jQuery的启发。

Ragel的另一个强大功能是它如何生成基于graphviz的图表,可视化状态机。以下是取自Zed Shaw'sarticle on ragel state charts的示例。

ragel state chart http://www.zedshaw.com/tips/HelloMachine_small.png

+0

非常好。我一定会检查一下! – chadmyers 2008-09-19 14:01:44

8

如果你正在寻找进入写作的独立的DSL,那么你寻找到建筑编译器 - 没有办法解决它。编译器构造必不可少的编程知识,它并不像通常想象的那么困难。 Steve Yegge的Righ Programmer Food总结了知道如何很好地编译编译器的价值。

有很多方法可以开始。我建议查看文章中提到的两篇论文:Want to write a compiler? Just read these Two papers。第一个,Let's build a compiler,非常方便。它使用Turbo Pascal作为实现语言,但您可以使用任何其他语言轻松实现它 - 源代码非常清晰。帕斯卡是一种简单的语言。

一旦你对事物的工作方式和术语有了一个好的感觉,我建议钻研ANTLR之类的东西。 ANTLR有一个很好的IDE,ANTLRWorks,附带一个解释器和一个调试器。它还可以快速生成语法真正非常好的可视化。我发现它在学习中非常宝贵。

ANTLR有几个很好的教程,尽管他们起初可能有点不知所措。 This one很好,虽然它不符合ANTLR 2.0,所以你可能遇到与更新版本不兼容(当前最新版本为3.1)。

最后,还有另一种DSL的方法:Lisp方法。鉴于Lisp的无语法特性(您的代码基本上是抽象语法树),您可以将无限制的语言形成它,只要您习惯了括号:)。

如果你确实采用这种方法,你想使用一个可嵌入的Lisp。在Java下,您有Clojure,这是一个Lisp方言,可与JVM及其库完美地互操作。我没有亲自使用它,但它看起来不错。对于Scheme,有GNU Guile,这是licensed under LGPL。对于Common Lisp,在LGPL下也有ECL。两者都使用C接口来实现互操作性,所以您几乎可以将它们嵌入到任何其他语言中。 ECL在Lisp中是独一无二的,因为每个Lisp函数都是作为一个C函数实现的,所以如果你想要的话,你可以用C语言编写Lisp代码(比如,在你自己的扩展方法中 - 你可以创建C函数来操作Lisp对象,然后从Lisp中调用它们)。我一直在使用ECL作为我的一个侧面项目,我喜欢它。维护人员非常积极和敏感。

+0

你不帮我在这里。哈哈我之前和ANTLR搞混了,我知道它的能力,但我希望有一些不太复杂/复杂的东西。我想我必须再看一次。 – chadmyers 2008-09-19 15:20:46

1

我一直在使用反讽效果很好。关于讽刺的很大一部分是,你可以很容易地将它包含在你将使用DSL的任何运行时。我正在创建一个外部DSL,我将其填充到用C#编写的语义模型中,因此非常好。然后我使用语义模型用StringTemplate生成代码。

1

如果您打算实施外部DSL,Spoofax(http://strategoxt.org/Spoofax)是一个很好的语言工作台。这是一个基于语法分析器的文本语言工作台,可以利用SDF,Stratego等几种最先进的技术。除了DSL实现之外,您还可以获得非常丰富的编辑器服务,例如代码完成,大纲视图,智能感知等。它已被用于构建多种语言,例如http://mobl-lang.org/。查看此信息以了解所提供的支持。

Spoofax项目带有一个开箱即用的样本DSL实现和一个Java代码生成器。它可能成为开始使用这些工具的起点。

以下教程详细介绍了此语言的工作台:http://strategoxt.org/Spoofax/Tour

希望它有帮助!

0

对于严重的外部DSL,您无法避免解析问题; ANTLR是你所需要的最少的。你想要检查的是程序转换系统,它可以用来将任意的DSL语法映射到像Java这样的目标语言。

http://en.wikipedia.org/wiki/Program_transformation

2

Xtext是专为这一点。

从网站:

的Xtext是编程语言和 领域特定语言的发展框架。它涵盖了完整的语言基础结构的所有方面,从 解析器,链接器,编译器或解释器到完整的顶尖的 Eclipse IDE集成。它具有所有这些方面的良好默认设置,同时每个单一方面都可以根据您的需求量身定制到 。