在实现模型驱动开发中,我们可以解释模型直接运行在领域框架之上,也可以把模型通过代码生成技术转换成代码之后编译运行在框架之上。这两种方式都有利弊,可以搭配使用,在OpenExpessApp中将采用这两种方法,类库通过代码生成,UI等元模型通过框架解释执行。由于代码生成是MDD中很重要的一项技术,所以本篇我将介绍一下代码生成相关的知识。
模型驱动中的代码生成
在EMF中,Metamodel为EMF元模型,Model为EMF模型;在MS DSL Tools中,MetaModel为DSL元模型,模板为T4模板
代码生成技术
- Antlr3
Antlr是一个非常著名的开源语言生成工具,官方网站是这么介绍的:
ANTLR, ANother Tool for Language Recognition, is a languagetool that provides a framework for constructing recognizers,interpreters, compilers, and translators from grammatical descriptionscontaining actions in a variety of targetlanguages. ANTLR provides excellent support for treeconstruction, tree walking, translation, error recovery, and errorreporting. There are currently about 5,000 ANTLR sourcedownloads a month.
研究过一阵子Antlr,用它来写过一个.Net下的表达式引擎,参考使用Antlr实现表达式引擎。
使用Antlr的一般经过如下步骤:
- 写语法
- 写StringTemplate模板(可选)
- 在AntlrWorks调试语法
- 从语法生成类
- 使用生成的类来写应用程序
作者写了一本介绍Antlr的专著 The Definitive Antlr Reference,我只是几年前大概看过一遍,觉得作者很牛。不过作者又出的另外一本书Language Implementation Patterns,有人说这本书更好,它将ANTLR内部的设计思想也讲得很清楚了。相比而言,之前那本书只能算是ANTLR的用户手册,而新书算是ANTLR的设计思想。
- Irony - .NET Language Implementation KitIrony是在Codeplex网站上的一个开源语言实现工具,官方介绍如下:
Irony is a development kit for implementing languages on .NET platform. It uses the flexibility and power of c# language and .NET Framework 3.5 to implement a completely new and streamlined technology of compiler construction. Unlike most existing yacc/lex-style solutions Irony does not employ any scanner or parser code generation from grammar specifications written in a specialized meta-language. In Irony the target language grammar is coded directly in c# using operator overloading to express grammar constructs. Irony's scanner and parser modules use the grammar encoded as c# class to control the parsing process. See the expression grammar sample for an example of grammar definition in c# class, and using it in a working parser.
......
代码生成定义语言
在特定领域建模 DSM(Domain Specific)介绍中介绍了DSM的不同工具的比较,其中代码生成定义语言也可以从表中看到,下面将会介绍一下DSL tools的T4和MetaEdit+的MERL(MetaEdit+ Reporting Language):
它的一个Report示例:
02 |
foreach .State [Watch] |
08 |
do ~From>()~To.State [Watch] |
它的语法定义如下:
001 |
STRING : "'" CHAR* "'" |
002 |
where CHAR is any character; a ' character must be doubled |
004 |
NAMECHAR : "a" .. "z" | "0" .. "9" | " " | {_+-[]?} | INTLNAMECHAR | ESCAPECHAR |
005 |
INTLNAMECHAR : {äëïöü} | {áéíóú} | {àèìòù} | {âêîôû} | {ñãœçÿ} | {߀} | {¿¡«»} |
006 |
ESCAPECHAR : "\" ECHAR |
007 |
where ECHAR is anything that is not a letter number or underscore |
009 |
If NAME contains a space, the whole name should have a ";" after it, or one of ".>~#" forming the start of the next element in a chainClause |
010 |
WILDNAME : [ "^" ] (NAMECHAR | "*" | "#" |