使用Xtext/Xtend 实现域专用语言DSL(2)
在前面的几篇博文中,我们已经介绍了如何用Xtext 来描述一个领域特定语言(DSL)的方法,你通常要对已经语法分析的EMF 模型(也就是语法抽象树AST)进行某种处理,比如转换成为另一种语言(例如Java,C++),配置文件,XML 文档等等。这就是代码生成。与之对应的,使用Xtend 语言来编写代码生成程序非常适合。Xtend在模型驱动的软件工程中使用了很多(用于模型到模型以及模型到文本的转换)。
Xtend是和xtext 相伴的程序设计语言,使用它实现语言翻译十分方便。xtend 的最大特点是它具有模板的功能,这项功能类似与php 产生动态web 网页的方式。用起来十分的方便。
Xtend本身是一种特定于领域的语言,它可以编译为Java,因此可以与现有Java程序无缝集成。Xtend提供了强大的功能,例如模板字符串,扩展方法,以及内置功能,例如过滤器,映射和归约。能够简洁地表达代码生成的程序。
你好,世界
您要用任何一种语言查看的第一件事都是Hello World示例。在Xtend中,其读为
class HelloWorld {def static void main(String[] args) {println("Hello World")}
}
您会看到Xtend看起来与Java非常相似。乍一看,主要的区别似乎是def
用于声明方法的关键字。就像在Java中一样,必须将类和main方法定义为应用程序的入口点。
Xtend类位于简单的Eclipse Java项目中。一旦安装了SDK,Eclipse将自动将所有类转换为Java源代码。默认情况下,您将在源文件夹xtend-gen中找到它。hello world示例已翻译为以下Java代码:
// Generated Java Source Code
import org.eclipse.xtext.xbase.lib.InputOutput;public class HelloWorld {public static void main(final String[] args) {InputOutput.<String>println("Hello World");}
}
表达式
非常奇怪的事情是在Xtend中不存在语句,所有内容都是表达式,并且具有返回类型。这使您能够以有趣的方式编写代码。例如,您可以try catch
在作业的右侧有一个表达式:
val data = try {fileContentsToString('data.txt')} catch (IOException e) {'dummy data'}
模板表达式(Template Expressions)
在DSL 代码生成过程中,使用最方便的就是模板表达式。利用模板可以生成一段目标代码的字符串,这个功能有点类似web 程序设计中的php语言。
模板被三重单引号('''
)包围。模板表达式可以跨越多行,并且可以嵌套对表达式进行求值,然后将其toString()
表示形式自动插入该位置。
例如:
def someHTML(String content) '''<html><body>«content»</body></html>
'''
«content» 中的内容是修改模板的脚本。它可以有IF,WHILE,FOR 等语句,也可以调用方法。这种方式在HTML 动态网页生成中经常会用到。
注意:使用CTRL + < 和 CTRL + > 输入
«
和 » 符号。
例如 : 我们可以编写一个产生content 的方法
def content(){
'''
<h1>Hello the world</h1>
<p> this is generated by xtend</P>
'''
}
模板中的注释
普通的单行注释//...
和多行注释/* ... */
将无法在模板表达式中使用。但是,您可以使用注释掉模板表达式内的完整行««« .....
。
def someHTML(String body) '''<html><body>««« this will not be visible in the result««« nor will this: «body»</body></html>
'''
模板中的条件
IF
模板中有一个特殊的用途:
def someHTML(Paragraph p) '''<html><body>«IF p.headLine != null»<h1>«p.headline»</h1>«ENDIF»<p>«p.text»</p></body></html>
'''
您也可以使用IF...ELSE...ENDIF
或IF...ELSEIF...ENDIF
表达式:
def someHTML(Paragraph p) '''<html><body>«IF p.headLine != null»<h1>«p.headline»</h1>«ELSE»<h1>«p.standartHeadline»</h1>«ENDIF»<p>«p.text»</p></body></html>
'''
模板中的循环
还有一个FOR
表达式可用:
def someHTML(List<Paragraph> paragraphs) '''<html><body>«FOR p : paragraphs»«IF p.headLine != null»<h1>«p.headline»</h1>«ENDIF»<p>«p.text»</p>«ENDFOR»</body></html>
'''
实例:DSL 代码生成
Xtend 的一个重要的应用是实现DSL 语言的代码生成。而DSL 语言是通过Xtext 来定义的。当你建立一个 DSL 的语法文件Test.mydsl后,你可以生成一个具有你的DSL 插件的Eclipse 编辑器。然后在这个编辑器上你可以输入符合你的DSL 语法的文本文件,并且会自动生成对应的代码。
编写代码生成程序
xtext 自动建立了一个代码生成的代码
package org.xtext.example.st.generatorimport org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.generator.AbstractGenerator/*** Generates code from your model files on save.* * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation*/
class STGenerator extends AbstractGenerator {override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {for (e : resource.allContents.toIterable.filter(typeof(StructuredTextAlgorithm))){fsa.generateFile('GenericFB.h', "hello the world" )}}
运行
要运行生成的编辑器,必须启动一个启用了DSL插件的新Eclipse工作台
- 选择运行->运行配置...
- 出现“运行配置”对话框。从Eclipse应用程序的上下文菜单中选择“新建”。
- 从Eclipse Application的上下文菜单中选择New。
- 转到“参数”选项卡,然后在“ VM参数”字段中输入 -Xmx256m以增加新Eclipse工作台的最大堆大小。
- 通过单击“运行”按钮启动新的Eclipse工作台。
注意:在Arguments VM Arguments 添加 -Xmx256m 很重要,我搞了两天Code 始终不能产生。添加了这个参数后成功了。
当Eclipse 编辑器启动后,你新建一个java 项目,然后在src 目录中新建一个符合你的DSL 语法的mydsl 文件,这时候编辑器会弹出一个对话框问你是否要转化成为xtext 项目,你选择yes。在mydsl 文件中输入你的dsl 程序或模型,当你编写完成,没有语法错误后,按save 按钮后,eclipse 编辑自动会在src-gen 目录中产生一个目标代码的程序。
下面是本人将PLC 的ST语言翻译成为C 的样子。很棒吧?你也是可以的。
独立的命令行编译器
除了在eclipse IDE 架构下能够生成代码之外,也可以生存一个独立的java 应用程序实现语言的翻译。下面介绍具体的过程
1 在MWE2的文件中添加下面的内容:
language = StandardLanguage {name = "org.example.entities.Entities"fileExtensions = "entities"...generator = {generateXtendMain = true}
}
注意:《Implementing Domain-Specific Languages with Xtext and Xtend》书的第五章好像是不对的,按照我这样的写。
2 运行MWE2 后你会发现在src/org.xtext.example.st.generator 目录下多了一个main.xtend 文件,
3 击右键 Run As | Java Application 这时在控制台下会出现“Aborting: no path to EMF resource provided!" 不要担心,因为你没有带任何命令参数。
4 文件菜单中选择 Export... | Java | Runnable JAR File,然后点击 Next.
5.按如下设参数
这时在你的目录中出现了ST-compiler.jar
6 运行
(base) yao@minipc:~$ java -jar ST-compiler.jar ./GenericFB.ST
Code generation finished.
(base) yao@minipc:~$
成功地生成了cpp 代码。
小结
带着问题去学习总是效率最高的,不过掌握的知识并不全面。我学习xtend 的目的是实现语言,模型的翻译。比如 PLC 的Structure Text 翻译成 C++代码。
使用Xtext/Xtend 实现域专用语言DSL(2)相关推荐
- ·使用Xtext/Xtend 实现域专用语言DSL(1)
本博文通过一个简单的例子介绍如何使用Xtext 编写一个简单DSL 的语法. 建立一个DSL语言 假设我们要建立一个DSL 语言来描述一个会议的信息:最终的描述文本是这样的: datatype Str ...
- 领域专用语言(DSL)简介
原文地址:http://blog.csdn.net/u010278882/article/details/50554299 主要回答几下几个问题 1 什么是 DSL 2 为什么使用 DSL 3 ...
- 位域外部申明_(外部)域特定语言的完整指南
位域外部申明 本指南将向您显示: 什么 :定义后,我们将研究19个DSL实例 原因 :使用DSL可以带来哪些具体好处? 方法 :我们将讨论构建DSL的不同方法以及成功的因素是什么 之后,您将获得一系列 ...
- 【Kotlin】Kotlin 领域特定语言 DSL 原理 二 ( 中缀表达式 )
文章目录 I . 中缀表达式 ( 中缀调用 ) II . 中缀表达式 ( 中缀调用 ) 示例代码 I . 中缀表达式 ( 中缀调用 ) 1 . 中缀表达式作用 : 中缀表达式是 Kotlin 领域特定 ...
- 会c 学plc编程语言,想学PLC编程?先弄清5种PLC专用语言!
PLC目前有5种标准的编程语言,包含图形化编程语言和文本化编程语言. 图形化编程语言包含:梯形图(LD-Ladder Diagram).功能块图(FBD - Function Block Diagra ...
- 自动化学计算机语言先学什么,要入门PLC编程 先搞清这5种专用语言
原标题:要入门PLC编程 先搞清这5种专用语言 PLC,(Programmable Logic Controller),乃是一种电子装置,早期称为顺序控制器"Sequence Control ...
- 域控 只能访问特定网址_开发人员需要了解的特定于域的语言
域控 只能访问特定网址 特定领域语言 (DSL)是一种旨在在特定域的上下文中使用的语言. 域可以是业务上下文(例如,银行,保险等)或应用程序上下文(例如,Web应用程序,数据库等).相反,通用语言(G ...
- xtext_使用Xtext为Eclipse和IntelliJ开发DSL
xtext 在这篇文章中,我们将看到如何开发一种简单的语言. 我们的目标是: 语言的解析器 IntelliJ的编辑器 . 编辑器应具有语法突出显示,验证和自动完成功能 我们还将免费提供Eclipse和 ...
- 使用Xtext为Eclipse和IntelliJ开发DSL
在这篇文章中,我们将看到如何开发一种简单的语言. 我们的目标是: 语言的解析器 IntelliJ的编辑器 . 编辑器应具有语法突出显示,验证和自动完成功能 我们还将免费提供Eclipse和Web编辑器 ...
最新文章
- Real-Time DNA Sequencing from Single Polymerase Molecules
- weblogic服务器保存图片失败解决办法
- Jquery中AJAX参数详细介绍
- 轻松搞定面试中的二叉树题目
- python枚举类的意义_用于ORM目的的python枚举类
- JAVA遇见HTML——JSP篇(JavaBeans)
- 招一个写代码的女生:国外女程序员是什么样的
- 单片机c语言二进制转10进制,51单片机用C语言怎么样把八位二进制转换成十进制...
- html元数据是什么意思,HTML meta 元数据标签
- 41.D3D数学库 GameProject7
- 最火的C语言编程软件,适合编写C语言代码的编程软件有哪些
- javassist修炼笔记
- QT绘制实时动态曲线——qcustomplot使用(一)
- 如果延迟退休势在必行,区块链如何助力“养老助老”?
- java:mysql基础语法
- LM2596-5.0开关电源电感的选取
- 【JDK7】新特性(7) 监听文件系统的更改
- CQYZ Online Judge P2995 萨鲁曼的大军(c++)
- HTML基础教学课件,HTML基础课件.ppt
- C# SolidWorks 二次开发 API-删除工程图中的图片与插入二维码