MDSF:代码生成(Code Generation)介绍

在实现模型驱动开发中,我们可以解释模型直接运行在领域框架之上,也可以把模型通过代码生成技术转换成代码之后编译运行在框架之上。这两种方式都有利弊,可以搭配使用,在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的一般经过如下步骤:

  1. 写语法
  2. 写StringTemplate模板(可选)
  3. 在AntlrWorks调试语法
  4. 从语法生成类
  5. 使用生成的类来写应用程序

  作者写了一本介绍Antlr的专著 The Definitive Antlr Reference,我只是几年前大概看过一遍,觉得作者很牛。不过作者又出的另外一本书Language Implementation Patterns,有人说这本书更好,它将ANTLR内部的设计思想也讲得很清楚了。相比而言,之前那本书只能算是ANTLR的用户手册,而新书算是ANTLR的设计思想。

       

  • Irony - .NET Language Implementation Kit
    Irony是在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):

  • MetaEdit+的MERL语言
    MetaEdit+提供代码生成编辑器,还支持生成的调试。OpenExpressApp采用类似MetaEdit+的元元模型来编写语言,所以将来的代码生成可能也会主要参考它来做。具体可参考安装程序目录中的User's Guides MetaEdit+ Workbench 代码生成章节内容


它的一个Report示例:

 

01Report 'Test'
02foreach .State [Watch]
03'State : '
04   :State name;
05   newline
06   'Connects to: '
07   newline
08   do ~From>()~To.State [Watch]
09   '   '
10      :State name;
11      newline
12   }
13   newline
14}
15endreport

 

它的语法定义如下:

001STRING  : "'" CHAR* "'"
002where CHAR is any character; a ' character must be doubled
003NUMBER  : ("0".."9")+
004NAMECHAR    : "a".."z" | "0".."9" | " " | {_+-[]?} | INTLNAMECHAR | ESCAPECHAR
005INTLNAMECHAR    : {äëïöü} | {áéíóú} | {àèìòù} | {âêîôû} | {ñãœçÿ} | {߀} | {¿¡«»}
006ESCAPECHAR  : "\" ECHAR
007where ECHAR is anything that is not a letter number or underscore
008NAME    : NAMECHAR+
009If 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
010WILDNAME    : ["^"] (NAMECHAR | "*" | "#")+
011If WILDNAME contains a space, the whole name should have a ";" after it.
012#   Design element access and output commands (5.3.2)
013chainOutputClause   : (propClauseWithLevel | propClause | (graphEltClause+ propClause)) [";"] [translatorNames] [";"];
014translatorNames : ("%" <NAMECHAR>+)+;
015propClauseWithLevel : propClause levelNumber [";"];
016levelNumber : [";"] " "* ["-"] <NUMBER>+;
017propClause  : ":" (<NAME> | "()");
018graphEltClause  : (objClause | relClause | roleClause | portClause) [";"]
019objClause   : "." typeChoiceClause
020relClause   : ">" typeChoiceClause
021roleClause  : "~" typeChoiceClause
022portClause  : "#" typeChoiceClause
023typeChoiceClause    : NAME
024    | "()"
025    | "( " WILDNAME {" | " WILDNAME}* ")"
026#   General commands (5.3.3)
027report  : oldreport | newreport;
028oldreport   : "report" <STRING> clause* "endreport";
029newreport:  [newheadersection] clause*;
030newheadersection    : <NAME> ["(" [<NAME> ("," <NAME>)*] ")" ];
031clause  : (comment
032| basicClause
033| ifClause
034| loop
035| subreportClause
036| fileClause
037| md5Clause
038| executeClause
039| promptAskClause
040| variableAssign
041| variableClause
042| translationClause
043| mathClause
044| chainOutputClause
045;
046comment : <comment>;
047basicClause : atomicClause | iterableClause;
048atomicClause    : newlineClause | separatorClause | literal | variableRef | simpleClause;
049newlineClause   : "newline" [";"];
050separatorClause : "sep" [";"];
051literal : <STRING> [translatorNames] [";"];
052variableRef     : "$" <NAME> [translatorNames] [";"];
053simpleClause    : ("id" | "type" | "metatype" | "oid" | "projectid" | "objectid" | "project") [levelNumber] [";"] [translatorNames] [";"]
054|
055("x" | "y" | "left" | "right" | "top" | "bottom" | "centerX" | "centerY" | "width" | "height" | "area") [levelNumber] [";"] [translatorNames] [";"];
056iterableClause  : ("decompositions" | "explosions" | "containers" | "contents" | "stack" | "graphs") [";"];
057#   Control and navigation commands (5.3.4)
058ifClause    : "if" [condition]
059"then" [";"] (clause* | ";")
060["else" [";"] clause*]
061"endif" [";"];
062condition   : ("not" condition)
063| (condition "and" condition)
064| (condition "or" condition)
065| ("(" condition ")")
066| expression;
067expression  : comparison | unary;
068unary   : comparableClause;
069comparison  : comparableClause comp comparableClause
070["num"];
071comparableClause    : atomicClause | chainClause;
072comp    : "<" | ">" | "<=" | ">=" | "=" | "<>" | "=~" | "=/";
073loop    : ("do" | "dowhile")
074(chainClause | atomicClause)
075[whereClause] [filterClause]
076"{" clause* "}" [";"]
077|
078"foreach"
079graphEltClause [";"]
080[whereClause] [filterClause]
081"{" clause* "}" [";"];
082chainClause : (chainElementClause [levelNumber] [";"])+;
083chainElementClause  : graphEltClause | propClause | iterableClause;
084whereClause : "where" condition;
085filterClause    : orderbyClause [uniqueClause]
086| uniqueClause;
087orderbyClause   : "orderby" orderCriterion ("," orderCriterion)*;
088uniqueClause    : "unique" [clause+ ("," clause+)*];
089orderCriterion  : clause+ ["num"] ["asc" | "desc"];
090subreportClause : ("subreport" | "subgenerator") [";"] clause* "run" [";"];
091#   External I/O commands (5.3.5)
092fileClause  : outputFileClause | filenameReadClause | filenamePrintClause;
093outputFileClause    : "filename" [";"] clause*
094["encoding" [";"] clause+]
095["md5start" [";"] clause+]
096["md5stop" [";"] clause+]
097modeClause clause*
098"close" [";"];
099modeClause  : ("write" | "merge" | "append") [";"];
100filenameReadClause  : "filename" [";"] clause*
101["encoding" [";"] clause+]
102"read" [";"];
103filenamePrintClause : "filename" [";"] clause* "print" [";"];
104md5Clause   : "md5id" [";"] clause* "md5Block" [";"]
105clause*
106"md5sum" [";"];
107executeClause   : ("external" | "internal") [";"]
108clause*
109("execute" | "executeBlocking") [";"];
110promptAskClause : "prompt" [";"] clause* "ask" [";"];
111#   String and number commands (5.3.6)
112variableClause  : variableReadClause | variableWriteClause;
113variableReadClause  : "variable" [";"] clause+ "read" [";"];
114variableWriteClause : "variable" [";"] clause+
115variableModeClause clause* [";"]
116"close" [";"];
117variableModeClause  : ("write" | "append") [";"];
118variableAssign  : "$" <NAME> "=" [";"] (variableAssign | basicClause | chainOutputClause);
119translationClause   : "to" [";"] clause*
120["translate" [";"] clause*]
121"endto" [";"];
122mathClause  : "math" [";"] clause* "evaluate" [";"];

书籍

What's Inside:

  • Code generation basics
  • CG techniques and best practices
  • Patterns of CG design
  • How to deploy generators
  • Many example generators

Includes generators for:

  • Database access
  • RPC
  • Unit tests
  • Documentation
  • Business logic
  • Data translation

 

       

LOP中的代码生成 

  LOP中的代码生成有三种主要的方法,我们将结合使用它们来定义模型转换;第一种是遍历方式,你枚举源模型中所有节点,检视每一个,并基于检视到的信息生成目标模型中的一些目标节点;第二种方式是使用模板和宏来定义如何生成目标语言;第三种方式是使用模式匹配来查找在源模型中的哪些节点上应用转换。

 

Code Generation by Model Transformation - A Case Study in Transformation Modularity

 

 

推荐:你可能需要的在线电子书

 

欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值