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

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

  在实现模型驱动开发中,我们可以解释模型直接运行在领域框架之上,也可以把模型通过代码生成技术转换成代码之后编译运行在框架之上。这两种方式都有利弊,可以搭配使用,在OpenExpessApp中将采用这两种方法,类库通过代码生成,UI等元模型通过框架解释执行。由于代码生成是MDD中很重要的一项技术,所以本篇我将介绍一下代码生成相关的知识。

模型驱动中的代码生成

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

在EMF中,Metamodel为EMF元模型,Model为EMF模型;在MS DSL Tools中,MetaModel为DSL元模型,模板为T4模板

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

代码生成技术

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

  • 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的设计思想。

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


  • 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.

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

……

代码生成定义语言

  在特定领域建模 DSM(Domain Specific)介绍中介绍了DSM的不同工具的比较,其中代码生成定义语言也可以从表中看到,下面将会介绍一下DSL tools的T4和MetaEdit+的MERL(MetaEdit+ Reporting Language):

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

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

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

它的一个Report示例:

 

  Report 'Test'
  foreach .State [Watch]
  {  'State : '
     :State name;
     newline
     'Connects to: '
     newline
     do ~From>()~To.State [Watch]
     {  ' 	'
        :State name;
        newline
     }
     newline
  }
  endreport 

 

它的语法定义如下:

STRING	: "'" CHAR* "'"
where CHAR is any character; a ' character must be doubled
NUMBER	: ("0".."9")+
NAMECHAR	: "a".."z" | "0".."9" | " " | {_+-[]?} | INTLNAMECHAR | ESCAPECHAR
INTLNAMECHAR	: {äëïöü} | {áéíóú} | {àèìòù} | {âêîôû} | {ñãœçÿ} | {߀} | {¿¡«»}
ESCAPECHAR	: "\" ECHAR
where ECHAR is anything that is not a letter number or underscore
NAME	: NAMECHAR+
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
WILDNAME	: ["^"] (NAMECHAR | "*" | "#")+
If WILDNAME contains a space, the whole name should have a ";" after it.
# 	Design element access and output commands (5.3.2)
chainOutputClause	: (propClauseWithLevel | propClause | (graphEltClause+ propClause)) [";"] [translatorNames] [";"];
translatorNames	: ("%" <NAMECHAR>+)+;
propClauseWithLevel	: propClause levelNumber [";"];
levelNumber	: [";"] " "* ["-"] <NUMBER>+;
propClause	: ":" (<NAME> | "()");
graphEltClause	: (objClause | relClause | roleClause | portClause) [";"]
objClause	: "." typeChoiceClause
relClause	: ">" typeChoiceClause
roleClause	: "~" typeChoiceClause
portClause	: "#" typeChoiceClause
typeChoiceClause	: NAME
	| "()"
	| "( " WILDNAME {" | " WILDNAME}* ")"
# 	General commands (5.3.3)
report	: oldreport | newreport;
oldreport	: "report" <STRING> clause* "endreport";
newreport: 	[newheadersection] clause*;
newheadersection	: <NAME> ["(" [<NAME> ("," <NAME>)*] ")" ];
clause	: (comment
| basicClause
| ifClause
| loop
| subreportClause
| fileClause
| md5Clause
| executeClause
| promptAskClause
| variableAssign
| variableClause
| translationClause
| mathClause
| chainOutputClause
;
comment	: <comment>;
basicClause	: atomicClause | iterableClause;
atomicClause	: newlineClause | separatorClause | literal | variableRef | simpleClause;
newlineClause	: "newline" [";"];
separatorClause	: "sep" [";"];
literal	: <STRING> [translatorNames] [";"];
variableRef 	: "$" <NAME> [translatorNames] [";"];
simpleClause	: ("id" | "type" | "metatype" | "oid" | "projectid" | "objectid" | "project") [levelNumber] [";"] [translatorNames] [";"]
|
("x" | "y" | "left" | "right" | "top" | "bottom" | "centerX" | "centerY" | "width" | "height" | "area") [levelNumber] [";"] [translatorNames] [";"];
iterableClause	: ("decompositions" | "explosions" | "containers" | "contents" | "stack" | "graphs") [";"];
# 	Control and navigation commands (5.3.4)
ifClause	: "if" [condition]
"then" [";"] (clause* | ";")
["else" [";"] clause*]
"endif" [";"];
condition	: ("not" condition)
| (condition "and" condition)
| (condition "or" condition)
| ("(" condition ")")
| expression;
expression	: comparison | unary;
unary	: comparableClause;
comparison	: comparableClause comp comparableClause
["num"];
comparableClause 	: atomicClause | chainClause;
comp	: "<" | ">" | "<=" | ">=" | "=" | "<>" | "=~" | "=/";
loop	: ("do" | "dowhile")
(chainClause | atomicClause)
[whereClause] [filterClause]
"{" clause* "}" [";"]
|
"foreach"
graphEltClause [";"]
[whereClause] [filterClause]
"{" clause* "}" [";"];
chainClause	: (chainElementClause [levelNumber] [";"])+;
chainElementClause	: graphEltClause | propClause | iterableClause;
whereClause	: "where" condition;
filterClause	: orderbyClause [uniqueClause]
| uniqueClause;
orderbyClause 	: "orderby" orderCriterion ("," orderCriterion)*;
uniqueClause 	: "unique" [clause+ ("," clause+)*];
orderCriterion	: clause+ ["num"] ["asc" | "desc"];
subreportClause	: ("subreport" | "subgenerator") [";"] clause* "run" [";"];
# 	External I/O commands (5.3.5)
fileClause	: outputFileClause | filenameReadClause | filenamePrintClause;
outputFileClause	: "filename" [";"] clause*
["encoding" [";"] clause+]
["md5start" [";"] clause+]
["md5stop" [";"] clause+]
modeClause clause*
"close" [";"];
modeClause	: ("write" | "merge" | "append") [";"];
filenameReadClause	: "filename" [";"] clause*
["encoding" [";"] clause+]
"read" [";"];
filenamePrintClause	: "filename" [";"] clause* "print" [";"];
md5Clause	: "md5id" [";"] clause* "md5Block" [";"]
clause*
"md5sum" [";"];
executeClause	: ("external" | "internal") [";"]
clause*
("execute" | "executeBlocking") [";"];
promptAskClause	: "prompt" [";"] clause* "ask" [";"];
# 	String and number commands (5.3.6)
variableClause	: variableReadClause | variableWriteClause;
variableReadClause	: "variable" [";"] clause+ "read" [";"];
variableWriteClause	: "variable" [";"] clause+
variableModeClause clause* [";"]
"close" [";"];
variableModeClause	: ("write" | "append") [";"];
variableAssign	: "$" <NAME> "=" [";"] (variableAssign | basicClause | chainOutputClause);
translationClause	: "to" [";"] clause*
["translate" [";"] clause*]
"endto" [";"];
mathClause	: "math" [";"] clause* "evaluate" [";"];

书籍

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

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

 

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

LOP中的代码生成 

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

 

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

 

 

推荐:你可能需要的在线电子书MDSF:代码生成(Code Generation)介绍

 

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101213.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • smb服务配置

    smb文件共享:用internet文件系统(CIFS)也称为服务器是适用于MicrosoftWindows服务器和客户端的标准文件和打印共享系统模块。Samba服务可用于将Linux文件系统作为CIFS/SMB网络文件共享进行共享,并将Linux打印机作为CIFS/SMB打印机共享进行共享。实验一、windows共享文件给linux1、实验环境1)、windows系统172.25.254…

    2022年4月13日
    35
  • Pycharm中的代码调试基本步骤

    Pycharm中的代码调试基本步骤文章目录步骤一、在所选行点击鼠标左键,此时会出现红点标记,若想取消再点击一次即可步骤二、在空白处单击鼠标右键,并点击DEBUG选项步骤三、点击控制台相关的功能按键就行调试步骤一、在所选行点击鼠标左键,此时会出现红点标记,若想取消再点击一次即可步骤二、在空白处单击鼠标右键,并点击DEBUG选项步骤三、点击控制台相关的功能按键就行调试…

    2022年8月28日
    5
  • MyCCL特征码定位原理学习[通俗易懂]

    MyCCL特征码定位原理学习[通俗易懂]这段时间学习WEB方面的技术,遇到了木马免杀特征码定位的问题,这里做一下学习笔记。这里对MyCCL的分块原理做一下探究对指定文件生成10个切块 对指定的木马进行切块后,文件列表是这样的。 注意这里是从E0作为切块的偏移量。也就是说从E0的位置开始逐个切块,E0之前的内容是保留的。这样做的目的是保留一些PE必须的头文件信息。我们来通过亲身的探究来解析一下MyCCL的切块区

    2025年8月15日
    4
  • MyBatis逆向工程_java maven

    MyBatis逆向工程_java maven什么是逆向工程    MyBatis的一个主要的特点就是需要程序员自己编写sql,那么如果表太多的话,难免会很麻烦,所以mybatis官方提供了一个逆向工程,可以针对单表自动生成mybatis执行所需要的代码(包括mapper.xml、mapper.java、po..)。一般在开发中,常用的逆向工程方式是通过数据库的表生成代码。1:mybatis逆向工程开发源码:https://do…

    2022年8月21日
    8
  • 微信公众平台、微信公众平台.小程序、微信.开放平台[通俗易懂]

    微信公众平台、微信公众平台.小程序、微信.开放平台[通俗易懂]一个开发者账号如何上线多个小程序?一个小程序账号对应一个小程序,可发布一个小程序上线。如果需要开发多款小程序,请注册新的账号。https://developers.weixin.qq.com/community/develop/doc/000886957d47f87cf9997f47c5b000小程序怎么发布,一套小程序代码怎么同时发布到不同的小程序上面,发布为体验版和正式版本!点击上传旁边的详情按钮,打开配置页面,修改项目addip,吧这个appid修改成需要覆盖的线上小程序id即可https:

    2022年6月16日
    44
  • java构造函数

    java构造函数

    2021年9月29日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号