Xtext——3. 十五分钟入门
来源:互联网 发布:一手淘宝买家数据 编辑:程序博客网 时间:2024/06/04 19:57
十五分钟入门
本章将实现一个小型的特定领域的语言来对实体和属性进行建模,类似于Rails、Grails、或Spring Roo。下面的语法还是很有吸引力的:
datatype String
entity Blog {
title: String
many posts: Post
}
entity HasAuthor {
author: String
}
entity Post extends HasAuthor {
title: String
content: String
many comments: Comment
}
entity Comment extends HasAuthor {
content: String
}
创建一个新的Xtext项目
首先需要创建几个Eclipse项目,通过Eclipse向导:
File->New->Project...->Xtext->Xtext project
选择一个有意义的项目名称、语言名称,以及文件扩展名。例如:
Main Project Name: org.example.domainmodel
Language Name: org.example.domainmodel.Domainmodel
DSL-File Extension: dmodel
通过向导完成项目的创建之后,在工作区中可以看到三个新项目,其中:
org.example.domainmodel包含了语法的定义和所有运行时组建(此法语法分析解析、链接、验证等)
org.example.domainmodel.tests为单元测试
org.example.domainmodel.ui是Eclipse编辑器,以及所有其他工作台相关的功能
自己制定语法
向导会自动在编辑器中打开语法文件Domainmodel.xtext,如下所示,其中含有简单的Hello World语法:
grammar org.example.domainmodel.Domainmodel with
org.eclipse.xtext.common.Terminals
generate domainmodel "http://www.example.org/domainmodel/Domainmodel"
Model:
greetings+=Greeting*;
Greeting:
'Hello' name=ID '!';
现在,将上边的语法替换为下面我们定义的域建模语言:
grammar org.example.domainmodel.DomainModel with
org.eclipse.xtext.common.Terminals
generate domainmodel "http://www.example.org/domainmodel/Domainmodel"
Domainmodel :
elements += Type*
;
Type:
DataType | Entity
;
DataType:
'datatype' name = ID
;
Entity:
'entity' name = ID ('extends' superType = [Entity])? '{'
features += Feature*
'}'
;
Feature:
many?='many'? name = ID ':' type = [Type]
;
Domainmodel :
elements += Type*
;
Type:
DataType | Entity
;
DataType:
'datatype' name = ID
;
Entity :
'entity' name = ID ('extends' superType = [Entity])? '{'
features += Feature*
'}'
;
然后是一个带有括号和可选项(?)的extends从句。因为名为superType的特性采用交叉引用(注意其中的中括弧),不会中总括弧中的规则Entity的进行解析,而仅仅对标示符进行解析(ID规则)。在链接过程中才会对Entity进行解析。最后,大括弧中可以有任意数量的Features,其采用下面的规则5。
5. 最后一个(并不是不重要),规则Feature的定义如下:Feature:
(many ?= 'many')? name = ID ':' type = [Type]
;
关键字many用来对域建模DSL中对一个多值特性进行建模,赋值操作符(?=)表明特性many的类型为boolean,目前 已经了解了解析规则中的其他语法元素。
域建模语法是Xtext的语法语言中最为重要的概念之一,已经了解到,关键字为一个字符串,然后通过简单的等于号(=)进行赋值,通过加等于(+=)进行多值赋值,通过文号等于(?=)进行布尔赋值。此外,了解了如何声明交叉引用,以及不同的赋值(?=表示可选,=任意数目,+=至少一次)。在第7节中会有更为详细的描述。现在来看一下这样的语言描述能做哪些事情。
生成语言
我们已经定义了语法,现在需要执行代码生成器来生成各种语言组建,在项目中选中文件GenerateDomainmodel.mwe2,点击右键 Run As -> MWE2 Workow,将会触发Xtext语言生成器,会生成解析器和序列化器,以及一些其他基础结构代码。可以在控制台的日志消息中看到相应的过程。
运行生成的IDE插件
现在,可以对IDE集成进行测试了。如果从Eclipse的菜单中选择Run -> Run Con gurations...,可以创建一个新的Eclipse应用,在左边树状列表中选择节点Eclipse Application并添加一个新的,给一个有意义的名称,然后到右边的Arguments那里配置VM arguments:
-XX:MaxPermSize=128m
-Xmx512m
需要确保所配置的内存大小足够运行一个新的Eclipse实力。现在可以通过点击Run来创建一个新的进程。
新启动的Eclipse工作台已经安装了刚才开发的插件。在新的工作太重,创建一个新的项目,例如File -> New ->Project... -> Java Project,然后添加一个新的文件,文件的扩展名为前面步骤中指定的扩展名(*.dmodel ),此时会打开所生成的编辑器,来试一下代码自动完成、语法高亮、语法验证、链接错误、突出显示、引用等功能。
第二次迭代:添加Package和Import
创建了第一个DSL,在编辑器看一下效果,现在对其进行进一步的改进。域建模语言应支持包(Packages),用来防止命名冲突,这样可以更好的适用于目标环境(Java)。一个Package可能含有Types和其他包。为了能够应用命名,还需要添加import声明。
最后,我们想要将前边所使用的模型和新的模型需求放到不同的文件中。
// datatypes.dmodel
datatype String
// commons.dmodel
package my.company.common {
entity HasAuthor {
author: String
}
}
// blogs.dmodel
package my.company.blog {
import my.company.common.*
entity Blog {
title: String
many posts: Post
}
entity Post extends my.company.common.HasAuthor {
title: String
content: String
many comments: Comment
}
entity Comment extends HasAuthor {
content: String
}
}
现在开始对语法进行改进。
1. 由于Domainmodel不在包含类型,而是包含包,因此,需要对入口规则进行修改。此外,需要定义通用的超类型Packages和Types:AbstractElement。
Domainmodel:
(elements += AbstractElement)*
;
AbstractElement:
PackageDeclaration | Type
;
PackageDeclaration:
'package' name = QualifiedName '{'
(elements += AbstractElement)*
'}'
;
AbstractElement:
PackageDeclaration | Type | Import
;
QualifiedName:
ID ('.' ID)*
;
Import:
'import' importedNamespace = QualifiedNameWithWildcard
;
QualifiedNameWithWildcard:
QualifiedName '.*'?
;
4. 最后一步是允许使用完整的命名来进行交叉引用。否则,只有import之后,才能进行引用。
Entity:
'entity' name = ID
('extends' superType = [Entity | QualifiedName])?
'{'
(features += Feature)*
'}'
;
Feature:
(many ?= 'many')? name = ID ':' type = [Type | QualifiedName]
;
grammar org.example.domainmodel.Domainmodel with
org.eclipse.xtext.common.Terminals
generate domainmodel "http://www.example.org/domainmodel/Domainmodel"
Domainmodel:
(elements += AbstractElement)*
;
PackageDeclaration:
'package' name = QualifiedName '{'
(elements += AbstractElement)*
'}'
;
AbstractElement:
PackageDeclaration | Type | Import
;
QualifiedName:
ID ('.' ID)*
;
Import:
'import' importedNamespace = QualifiedNameWithWildcard
;
QualifiedNameWithWildcard:
QualifiedName '.*'?
;
Type:
DataType | Entity
;
DataType:
'datatype' name=ID
;
Entity:
'entity' name = ID
('extends' superType = [Entity | QualifiedName])?
'{'
(features += Feature)*
'}'
;
Feature:
(many ?= 'many')? name = ID ':' type = [Type | QualifiedName]
;
[转载请标明出处http://blog.csdn.net/donhao/article/details/7182792]
英文原文地址:http://www.eclipse.org/Xtext/documentation/2_1_0/020-domainmodel-step-by-step.php
- Xtext——3. 十五分钟入门
- Xtext——4. 十五分钟入门——进阶
- Xtext——2. 五分钟入门
- Xtext——10. Xtext 2.2中的新特性
- Xtext——1. 安装
- Xtext——11. 概述
- Xtext——6. 安装antlr
- Xtext——7. Xtend之概述
- Xtext——9. Xtend之表达式
- Xtext——12. 语法语言
- 【入门】十五分钟介绍 Redis数据结构
- 十五分钟快速入门系列:Python基础
- Xtext——8. Xtend之类和函数
- Xtext——6. 简单的五步来支持JVM语言
- Python词云 wordcloud 十五分钟入门与进阶
- Python中文分词 jieba 十五分钟入门与进阶
- Python中文分词 jieba 十五分钟入门与进阶
- Python中文分词 jieba 十五分钟入门与进阶
- 何时会发生db file sequential read等待事件?
- 关于高维空间的个人理解
- SQL调优:Clustering Factor影响数据删除速度一例
- MongoDB入门6——查询(二)
- VisualC++信息安全编程(6)穿透卡巴斯基的键盘记录编程-网络战技术
- Xtext——3. 十五分钟入门
- android 设置Button或者ImageButton的背景透明
- 『程序员』win7下的小隐藏的小软件
- 设计模式 reactor和proactor(转)
- 1556
- android笔记3(surfaceview)
- Android OpenGL ES
- 电子书RSS
- MFC 保存对话框扩展名