使用Xtext/Xtend 实现域专用语言DSL(2)

3 篇文章 5 订阅

在前面的几篇博文中,我们已经介绍了如何用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...ENDIFIF...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.generator

import 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++代码。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Learn how to implement a DSL with Xtext and Xtend using easy-to-understand examples and best practices About This Book Leverage the latest features of Xtext and Xtend to develop a domain-specific language. Integrate Xtext with popular third party IDEs and get the best out of both worlds. Discover how to test a DSL implementation and how to customize runtime and IDE aspects of the DSL Who This Book Is For This book is targeted at programmers and developers who want to create a domain-specific language with Xtext. They should have a basic familiarity with Eclipse and its functionality. Previous experience with compiler implementation can be helpful but is not necessary since this book will explain all the development stages of a DSL. What You Will Learn Write Xtext grammar for a DSL; Use Xtend as an alternative to Java to write cleaner, easier-to-read, and more maintainable code; Build your Xtext DSLs easily with Maven/Tycho and Gradle; Write a code generator and an interpreter for a DSL; Explore the Xtext scoping mechanism for symbol resolution; Test most aspects of the DSL implementation with JUnit; Understand best practices in DSL implementations with Xtext and Xtend; Develop your Xtext DSLs using Continuous Integration mechanisms; Use an Xtext editor in a web application In Detail Xtext is an open source Eclipse framework for implementing domain-specific languages together with IDE functionalities. It lets you implement languages really quickly; most of all, it covers all aspects of a complete language infrastructure, including the parser, code generator, interpreter, and more. This book will enable you to implement Domain Specific Languages (DSL) efficiently, together with their IDE tooling, with Xtext and Xtend. Opening with brief coverage of Xtext features involved in DSL implementation, including integration in an IDE, the book will then introduce you to Xtend as this language will be used in all the examples throughout the book. You will then explore the typical programming development workflow with Xtext when we modify the grammar of the DSL. Further, the Xtend programming language (a fully-featured Java-like language tightly integrated with Java) will be introduced. We then explain the main concepts of Xtext, such as validation, code generation, and customizations of runtime and UI aspects. You will have learned how to test a DSL implemented in Xtext with JUnit and will progress to advanced concepts such as type checking and scoping. You will then integrate the typical Continuous Integration systems built in to Xtext DSLs and familiarize yourself with Xbase. By the end of the book, you will manually maintain the EMF model for an Xtext DSL and will see how an Xtext DSL can also be used in IntelliJ. Style and approach A step-by step-tutorial with illustrative examples that will let you master using Xtext and implementing DSLs with its custom language, Xtend. Table of Contents Chapter 1: Implementing a DSL Chapter 2: Creating Your First Xtext Language Chapter 3: Working with the Xtend Programming Language Chapter 4: Validation Chapter 5: Code Generation Chapter 6: Customizing Xtext Components Chapter 7: Testing Chapter 8: An Expression Language Chapter 9: Type Checking Chapter 10: Scoping Chapter 11: Continuous Integration Chapter 12: Xbase Chapter 13: Advanced Topics Chapter 14: Conclusions
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值