簡體   English   中英

從Java模型使用XText生成DSL文件

[英]Generate DSL file with XText from Java model

我最近開始使用XText。 到目前為止,我已經能夠定義一個簡單的語法,完成JvmModelInferrer並生成相應的java類和.java文件。

是否可以從一組自定義Java類自動生成DSL文件(考慮其語法)?

讓我提供一個簡單的例子。

我有以下語法:

MODEL:
    entities+=ENTITY*
;

ENTITY:
    'entity' name=ValidID 'as'
        (elements+=PROPERTY)*
    'end'
;

PROPERTY:
    (many?='many')? 'property' name=ID 'of' type=JvmTypeReference
;

如果我有以下sample.myDsl

entity Book as
    property title of String
    property numPages of Integer
end

entity Author as
    property name of String
    property surname of String
end

我得到了Book.java和Author.java文件。 在我的項目中,我有一個處理器來分析java文件並從中創建對象,因此,如果我在先前的Book.java和Author.java上運行該處理器,則會得到兩個自定義Entity Java類型的實例。 每個Entity實例將具有一組Property實例。 因此,Java模型與xtext語法非常相似。

是否可以將這兩個對象“饋送”到XText,也許定義一個Inferrer來指定翻譯,並考慮相同的.xtext語法文件,自動生成一個.myDsl文件?

使用xtext,通常沒有問題

  • 創建模型為ast
  • 將其添加到資源
  • 保存資源以使其序列化

如果您使用xbase和jvmmodelinferrrer來構建ast,這可能是一種痛苦,如果您從模型中引用到一個推斷的jvm元素或嘗試以ast形式構建xbase表達式,那么這是使用domainmodel示例的一個簡單的復雜示例

package org.eclipse.xtext.example.domainmodel.tests

import com.google.inject.Injector
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.xtext.common.types.JvmParameterizedTypeReference
import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.example.domainmodel.DomainmodelStandaloneSetup
import org.eclipse.xtext.example.domainmodel.domainmodel.DomainmodelFactory
import org.eclipse.xtext.resource.DerivedStateAwareResource
import org.eclipse.xtext.resource.SaveOptions
import org.eclipse.xtext.xbase.jvmmodel.JvmTypeReferenceBuilder

class Main {
    var static extension DomainmodelFactory factory = DomainmodelFactory.eINSTANCE

    def static void main(String[] args) {
        var Injector injector = new DomainmodelStandaloneSetup().createInjectorAndDoEMFRegistration()
        val ResourceSet resourceSet = injector.getInstance(ResourceSet)
        val Resource r0 = resourceSet.createResource(URI.createURI("base/Base.dmodel"))
        val Resource r1 = resourceSet.createResource(URI.createURI("model/Person.dmodel"))
        val typeReferenceBuilder = injector.getInstance(JvmTypeReferenceBuilder.Factory).create(resourceSet)
        val typeReferences = injector.getInstance(TypeReferences)
        val model = createDomainModel
        r1.contents += model
        val model0 = createDomainModel
        r0.contents += model0
        // build the ast using xtends with clause
        model0 => [
            elements += createPackageDeclaration => [
                name = "base"
                elements += createEntity => [
                    name = "Base"
                    features+= createProperty => [
                        name = "id"
                        type = typeReferenceBuilder.typeRef("java.lang.String")
                        println(type)
                    ]
                ]
            ]
        ]
        //trigger the inferrer on resource 0
        (r0 as DerivedStateAwareResource) => [
            fullyInitialized = false
            installDerivedState(false)
        ]

        // build the ast of the second resource
        model => [
            elements += createPackageDeclaration => [
                name = "model"
                elements += createEntity => [
                    val base = typeReferences.findDeclaredType("base.Base", resourceSet)
                    println(base)
                    superType = typeReferenceBuilder.typeRef(base) as JvmParameterizedTypeReference
                    println(superType)

                    name = "Person"
                    features+= createProperty => [
                        name = "name"
                        type = typeReferenceBuilder.typeRef("java.lang.String")
                        println(type)
                    ]
                ]
            ]
        ]
        //save the resources
        r0.save(SaveOptions.defaultOptions.toOptionsMap)
        r1.save(SaveOptions.defaultOptions.toOptionsMap)
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM