那么现在,编译分为两个阶段:一个简单的从目标语言到最终结果的翻译,一个更复杂的从最初的原始语言到中间目标语言的转换;翻译阶段是微不足道的,因此我们把精力集中于更有意思的转换阶段;至少,现在的问题简化为了如何将模型从一种语言转换到另一种语言;但是,有可能源语言与目标语言是完全不同的,导致转换非常复杂,比如映射一个源节点到许多散布在目标模型中的目标节点;我们想让定义转换尽可能的简单容易,因此我们需要一种模型转换DSL来帮助我们;在MPS中,这种 DSL被称为Transformation Language
代码生成有三种主要的方法,我们将结合使用它们来定义模型转换;第一种是遍历方式,你枚举源模型中所有节点,检视每一个,并基于检视到的信息生成目标模型中的一些目标节点;第二种方式是使用模板和宏来定义如何生成目标语言;第三种方式是使用模式匹配来查找在源模型中的哪些节点上应用转换
我们通过定义DSLs把这些方式结合起来以支持任何一种方法;这些DSLs将一起工作来帮助你定义从一种语言到另一种语言的转换;例如,遍历方式激发了 Model Query Language的灵感,它使枚举节点和从概念模型中收集信息变得简单容易;你可以把它想象成某种针对概念模型的SQL;做为一种额外的奖赏,拥有一种强大的查询语言不只是对代码生成有用(例如,能够使编辑器更聪明)
Templates
模板方法工作方式类似Velocity或者XSLT;模板看起来很像目标语言,但是允许你在模板的任何部分中添加宏;宏本质上是当运行转换的时候被执行的代码段;宏允许你检视源模型(使用Model Query Language),并使用得到的信息对模板进行“填空”,得到最终的目标代码
在图5中,你可以看到为概念“Property”生成Java代码的模板的定义,模板为属性添加了field declarations, getters, setters等;这个模板是将代码从Structure Language转换为Java的生成器的一部分
既然模板看起来像目标语言,你可以想象模板是用某种基于目标语言的特殊的语言编写的;这也是它事实上的工作方式;我们实际上使用一个生成器来为你生成模板语言,而不是手工为每一种可能的目标语言创建模板语言;它基本上是复制目标语言,并添加所有模板特定的特性,诸如宏等;甚至模板编辑器也是从目标语言编辑器产生的,因此你同样不需要处理代码
当你使用一种模板语言的时候,你可以认为它是用目标语言编写的,只是某些部分的代码是参数化的,或者是由宏来计算的;这种技术极大的帮助简化了代码生成;模板还可以用在其它任务上,如重构、代码优化、还有更多...
Patterns
模型的模式匹配方法给我们一种作为Model Query Language的代替的查找模型的强大方法;你可以把模式想象成概念模型的正则表达式;与模板方法类似,我们基于源语言产生模式语言;模式语言看起来像源语言,只是添加了一些特性,来帮助你定义处理复杂源模型匹配的灵活的标准;你可以把这种方法想象成一种强大的“查找替换”的技术;再一次,模式语言不只是对代码生成有用,例如,它们在为源语言编辑器编写自动化的代码检查工具方面非常有用
文章来源于领测软件测试网 https://www.ltesting.net/