xtext语法示例

定义出的语法以下: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]
;
复制代码
相关文章
相关标签/搜索