定义出的语法以下:bash
datatype String
entity Blog{
title: String
many posts: Post
}
entity HasAuthor{
author: String
}
entity Post extends HasAuthor{
title: String
content: String
many commnets: Comment
}
entity Comment extends HasAuthor{
content: String
}
复制代码
一、语法中第一个规则一般做为入口或者开始的规则eclipse
Domainmodel:
elements += Type*
;
复制代码
Domainmodel包含任意数量(*)的Type,且该Type会被加到(+=)一个名为elements的特性中去。post
二、Type的规则代表Type是规则DataType或者(|)规则Entity。ui
Type:
DataType | Entity
;
复制代码
三、规则DataType以关键字“datatype”开始,后面跟着一个标示符,该标示符被解析为规则ID,其中规则ID的定义在语法超集org.eclipse.xtext.common.Terminals中,规则ID是一个单词,即标示符。spa
DataType:
'datatype' name = ID
;
复制代码
四、规则Entity也是以一个关键字开头,后面跟着一个名称(name)。code
Entity:
'entity' name = ID ('extends' superType = [Entity])? '{'
features += Features*
'}'
;
复制代码
后面是一个带有括号和可选项(?)的extends从句。由于名为superType的特性采用交叉引用(注意其中的中括弧),不对中括弧中的规则Entity进行解析,而仅仅对标示符进行解析(ID)。在连接过程当中才会对Entity进行解析。最后,大括弧中能够由任意数量的Features。blog
五、Feature规则的定义以下:ip
Feature:
(many ?= 'many')? name = ID ':' type = [Type]
;
复制代码
关键字many是用来对域建模DSL中对一个多值特性进行建模,赋值操做(?=)代表特性many的类型为boolean。element
改进后语法定义字符串
//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.commom HasAuthor{
title: String
content: String
many comments: Comment
}
entity Comment extend HasAuthor{
content: String
}
}
复制代码
语法改进
一、因为Domainmodel不但包含类型并且包含包,所以,须要对入口进行修改。此外,须要定义通用的超类型Packages和Types:AbstractElement
Domainmodel:
(elements += AbstractElement)*
;
AbstractElement:
PackagesDeclaration | Type
;
复制代码
二、PackageDeclaration包含一系列的Imports和AbstractElements,由于Imports能够做为root-Domainmodel,因此讲Import加入到AbstractElement中
PackageDeclaration:
'package' name = QualifiedName '{'
(elements += AbstractElement)*
'}'
;
AbstractElement:
PackageDeclaration | Type | Import
;
QualifiedName:
ID ('.' ID)*
复制代码
QualifiedName有一点特殊,其不包含任何赋值。所以仅做为数据类型规则,返回一个字符串。所以Package的特性name是String类型
三、使用xtext,能够很方便的定义imports。若是在解析规则中使用ImportedNameSpace,基础结构将会视其为import,甚至支持通配符。
Import:
'import' importNamespace = QualifiedNameWithWildcard
;
QualifiedNameWithWildcard:
QualifiedName '.*'?
;
复制代码
同QualifiedName相似,QualifiedNameWithWildcard返回一个字符串。
四、最后一步是容许用完整的命名来交叉引用,不然,只有import以后,才能进行引用。
Entity:
'entity' name = ID ('extends' superType = [Entity | QualifiedName])?
'{'
(features += Feature)*
'}'
;
Feature:
(many ?= 'many')? name = ID ':' type = [Type | QualifiedName]
;
复制代码