定義出的語法以下: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]
;
複製代碼