Spoofax是一个帮助开发者快速开发领域特定语言的一个平台,你可以使用它开发出属于自己的语言,并且拥有一个全功能的Eclipse插件,具有语言编辑和编译的功能。
关于领域特定语言
领域特定语言(domain-specific languages,简称DSL)并不是什么新奇的事物,它不同与C、Java这类通用语言(general-purpose language),DSL具有表达受限的特性,功能上也是为了某种实际的需要,特别设计的。比较广为认知的DSL,有数据库查询语言——SQL,网页设计中的级联样式表——CSS,它们都具有表达受限的特性,并且为了某种特殊的目的设计。可见DSL在编程届流行已久,它不停的改变程序员看待编程的角度。关于更多DSL的知识,可以参考Martin Fowler的《领域特定语言》一书。关于Syntax Definition Formalism
设计语言一个重要的一个环节是定义语法,尽管领域特定语言的语法可以设计的很简单,但是我们有了Spoofax这个有力的工具,理论我们可以把我们的DSL的语法设计的如同通用语言一样复杂。尽管实际情况中太复杂的语法并没有必要,但是语法制导的语言比分隔符制导的语言更具有可读性,能代表更多的语义,让DSL具有一定的语法规则应该是个不错的选择。在Spoofax中我们设计DSL的语法由SDF(syntax definition formalism)语言定义,SDF由一系列的产生式(production)组成。理解SDF首先必须了解编译原理的相关知识,产生式、语法树一些概念。
Spoofax会把源文件(由DSL编写)通过SDF定义的语法规则,生成抽象语法树(在Spoofax中直接生成语法树,简化了编译过程)
关于Stratego
其次就是翻译(transformation)的过程,在Spoofax中翻译规则由Stratego语言定义,Stratego由一系列的重写规则(rewrite rules)组成,把一个语法树转换成另一个语法树,或者转换成另外一个目标语言。类比C语言的编译过程,C编译器把C语言(源语言)文本,转换成抽象语法树,然后生成汇编语言(目标语言),(注意,C编译器实际工作远比这复杂,例如预处理,词法分析,最后还要链接生成可执行文件,这里只是简单举例)。而Spoofax通过SDF定义的产生式,把用DSL编写的源文件转换成抽象语法树,再通过Stratego定义的重写策略,翻译成目标语言(或者中间会转换成其他语法树)。
Spoofax到底能做什么呢?在实践开发中,我们往往面临大量的重复编码,错综复杂的业务和技术细节交织在一起,因为一些框架、库把一些通用部分抽象出来,努力使开发者从底层细节解脱出来,尽管库已经能解决很大一部分问题,但是使用库或者框架还是需要开发者了解非常多的技术细节,但这也比自己维护“轮子”轻松的多。例如,使用Struts这类MVC框架,开发者依然要编写大量的XML配置文件驱动框架,从某种意义上说这种配置文件也是一种DSL,但是它其实只是具有树结构的数据结构。因此DSL大有可为,用其丰富的语义表现复杂的逻辑。
当有了Spoofax这样的工作台,构建DSL的成本越来越低,我们可以使用它设计一种DSL,解决团队中经常碰到的一些问题,它们中有些甚至很难用库去抽象(或者开发库的成本太大),我们大可以设计一种语法简单不关心技术细节,只关心业务的语言的DSL,去生成复杂的目标语言。为了一两个程序去开发一种DSL未免太大材小用,但是实际情况中,一个团队接手的项目总是类似的,业务大同小异,设计一种DSL的成本往往能得到回报,当然前提是设计得当,否则可能会增加项目的复杂度。