2016-01-25 3 views
0

Я недавно начал работать с XText. До сих пор я мог определить простую грамматику, заполнить JvmModelInferrer и сгенерировать соответствующие классы java и .java-файлы.Сгенерировать DSL-файл с XText из Java-модели

Можно ли автоматически генерировать DSL-файл (с учетом его грамматики) из набора пользовательских классов Java?

Позвольте мне привести простой пример.

У меня есть следующая грамматика:

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. Каждый экземпляр Entity имел бы набор экземпляров Property. Итак, модель Java очень похожа на грамматику xtext.

Возможно ли «передать» эти два объекта XText, возможно, определить Inferrer для указания переводов и с учетом того же файла грамматики .xtext, автоматически генерировать файл .myDsl?

ответ

0

с XText это не Ususally никаких проблем

  • создать модель как аст
  • добавить к ресурсу
  • сохранить ресурс, чтобы получить его сериализовать

если вы используете xbase и jvmmodelinferrrer, построение ast может быть своего рода болью, если вы ссылаетесь от модели на выведенный элемент jvm или пытаетесь построить выражения xbase как ast - это простой пример с использованием примера 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) 
    } 

} 
Смежные вопросы