java - 从 Java 模型生成带有 XText 的 DSL 文件

标签 java xtext xbase

我最近开始使用 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 类型的两个实例。每个实体实例都有一组属性实例。因此,Java 模型与 xtext 语法非常相似。

是否可以将这两个对象“馈送到”XText,也许定义一个 Inferrer 来指定翻译,并考虑到相同的 .xtext 语法文件,自动生成 .myDsl 文件?

最佳答案

使用 xtext 通常没有问题

  • 将模型创建为 ast
  • 将其添加到资源
  • 保存资源以使其序列化

如果您使用 xbase 和 jvmmodelinferrrer 构建 ast 可能会很痛苦,如果您从模型引用推断的 jvm 元素 或者尝试将 xbase 表达式构建为 ast 这是一个使用域模型示例的简单复杂示例

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)
    }

}

关于java - 从 Java 模型生成带有 XText 的 DSL 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34998282/

相关文章:

java - Guava:如何将 Collection<T> 转换为 Collection<Optional<T>>?

java - MediaPlayer 出现错误

java - eclipse xtext : How can I know if file contain errors

java - XText注册全局变量

database - 如何将基于 xBase 的 ERP 连接到 Web 应用程序?

java - 如何在 Windows 的露天共享中部署自定义主题?

java - 如何在运行时从 jar 加载工作目录中的 .class?

java - Xtext 和 Xtend - 在方法中的参数之前添加注释

css - Aptana Studio 3 (.less) 的高级自定义语法着色