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]
;
複製代碼
相關文章
相關標籤/搜索