Compiler construction 构建有效的外部DSL

Compiler construction 构建有效的外部DSL,compiler-construction,dsl,Compiler Construction,Dsl,有什么工具可以让我构建一个真正的、诚实的外部DSL。不,我不是说滥用Ruby、Boo、XML或其他现有语言或语法,我指的是真正的外部DSL——我自己的语言用于我自己的目的 我知道有一些语言工作台正在开发中,我也听说过类似.NET的“讽刺”之类的事情。当然,还有ANTLR,Lex/Yaac等等,但我担心这些太复杂了,我不想做什么 请谈谈您可能使用过或听说过的DSL builder工具,以及您对它的帮助和缺点的印象。您真的应该去看看。它是一个在常规源代码中嵌入状态机的框架。Ragel支持C、C++、

有什么工具可以让我构建一个真正的、诚实的外部DSL。不,我不是说滥用Ruby、Boo、XML或其他现有语言或语法,我指的是真正的外部DSL——我自己的语言用于我自己的目的

我知道有一些语言工作台正在开发中,我也听说过类似.NET的“讽刺”之类的事情。当然,还有ANTLR,Lex/Yaac等等,但我担心这些太复杂了,我不想做什么


请谈谈您可能使用过或听说过的DSL builder工具,以及您对它的帮助和缺点的印象。

您真的应该去看看。它是一个在常规源代码中嵌入状态机的框架。Ragel支持C、C++、Objul-C、D、java和Ruby。 Ragel非常适合编写文件和协议解析器以及单步处理外部DSL内容。主要是因为它允许您在状态转换等方面执行任何类型的代码

使用Ragel的几个著名项目是,一个很棒的RubyWeb服务器。还有一个基于ruby的html解析器,它的灵感来源于jQuery

Ragel的另一个重要特性是它如何生成基于图形的图表来可视化您的状态机。下面是一个例子


如果你想编写独立的DSL,那么你就要考虑构建编译器——没有办法。编译器构造是基本的编程知识,并不像人们通常认为的那样困难。SteveYegge总结了知道如何很好地构建编译器的价值

有很多方法可以开始。我建议查看文章中提到的两篇论文:。第一个,非常容易接近。它使用Turbo Pascal作为实现语言,但您可以轻松地用任何其他语言实现它——源代码非常清晰。Pascal是一种简单的语言

一旦你对事物的运作方式和所涉及的术语有了很好的了解,我建议你深入研究一下。ANTLR有一个很好的IDE,它带有一个解释器和一个调试器。它还可以实时生成语法的非常好的可视化效果。我发现它在学习中是无价的

ANTLR有几个很好的教程,虽然一开始可能有点让人不知所措。很好,尽管它是针对AntlR2.0的,所以您可能会遇到与较新版本(目前最新版本是3.1)不兼容的问题

最后,还有另一种DSL方法:Lisp方法。考虑到Lisp的无语法特性(您的代码基本上是抽象语法树),只要您习惯了括号,就可以从中形成无数的语言:)


如果使用这种方法,您需要使用可嵌入的Lisp。在Java下,您可以使用一种Lisp方言,它可以与JVM及其库完美地互操作。我没有亲自用过,但看起来不错。对于Scheme,有GNU,它是。对于Common Lisp,在LGPL下还有。两者都使用C接口实现互操作性,因此您几乎可以将它们嵌入到任何其他语言中。ECL在Lisp中是独一无二的,因为每个Lisp函数都是作为C函数实现的,所以如果您愿意,可以用C编写Lisp代码(比如,在您自己的扩展方法中——您可以创建在Lisp对象上操作的C函数,然后从Lisp中调用它们)。我已经有一段时间在我的一个辅助项目中使用ECL了,我喜欢它。维护人员非常活跃,反应迅速。

我已经在Boo、Irony.NET和一个名为Grammatica的工具包中编写了DSL。你说解析器生成器太复杂了,但你的判断可能太仓促了,事实上,一旦你通过了一个小的学习曲线,它们就非常容易使用,并且打开了一个可以轻松覆盖工作的巨大可能性世界。我发现学习为大多数解析器生成器编写语法所需的符号有点类似于学习正则表达式——你必须稍微弯曲你的思维才能让它们进入,但回报是巨大的

我的观点是:如果您的目标语言足够简单,可以由一个简单的可视化设计器来处理,那么使用解析器生成器为其编写语法应该相当容易

如果你的目标DSL足够复杂,以至于你需要在写语法的时候大汗淋漓,那么这个简单的可视化工具无论如何都不会成功,你最终还是要学会写语法

不过,从长远来看,我同意内部DSL与外部DSL的区别。我在Boo中编写了一个内部DSL,不得不修改我的DSL语法以使其正常工作,而且它总是感觉像是一个黑客。同样的语法使用Irony.NET或ANTLR也同样容易实现,而且更加灵活

我有一个计划,正在讨论一些选择。这篇文章的中心是为运行时表达式求值编写DSL,但工具都是一样的


我对Irony.NET的体验都是积极的,有几个参考语言是使用Irony.NET实现的,这是一个很好的起点。如果你的语言很简单,那么你的启动和运行绝对不复杂。CodeProject上还有一个名为TinyParser的库,这个库非常有趣,因为它以纯源代码的形式生成解析器,这意味着您的最终产品完全没有任何第三方引用。不过,我自己也没用过。

我一直在用反讽,效果很好。具有讽刺意味的是,您可以轻松地将其包含在将使用DSL的任何运行时中。我正在创建一个外部DSL,并将其填充到一个用C#编写的语义模型中,所以讽刺是很好的。然后我使用语义模型用StringTemplate生成代码。

如果您计划实现外部DSL,Spoofax()是一个很好的语言工作台。它是一个基于解析器的文本语言工作台,利用了几种最先进的技术,如SDF、Stratego。除了t