首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Xtext啮合Acceleo

用Xtext啮合Acceleo
EN

Stack Overflow用户
提问于 2012-08-15 09:18:16
回答 1查看 1.3K关注 0票数 2

我正在进行Acceleo转换,目的是从输入的UML模型中生成代码(即Java)。

这个UML模型的一些元素(即活动不透明的动作)包含一些符合Xtext语法的文本,我想在Acceleo转换中获得等价的AST Ecore表示。

为此,我开发了一个Java类,它的方法以一个字符串作为输入,其中包含DSL摘录,并生成一个符合它的Ecore模型(更多细节请参见901947 )。我已经在一个单独的Java应用程序中测试了它,而且它似乎正常工作。

因此,我编写了一个简单的Acceleo模块(即getDSLModel),包装了这个java类,并使我能够从DSL文本表示中获得Ecore模型。

假设我的DSL (和等效的Ecore)由一个名为DSLModel的根元素组成,它包含(0..*)个DSLStatements (这是一个简化)。在Acceleo中,我从包含正确DSL脚本的字符串调用包装器时,我注意到它正确地返回了一个ModelImpl

代码语言:javascript
复制
    ['statement1;statement2'.getDSLModel()/]

所以Java服务和Xtext解析是可以工作的。

但是,如果我试图获得模型语句,即:

代码语言:javascript
复制
  ['statement1;statement2'.getDSLModel().statements/]

它返回一个“无效”字符串。所以我不能在for循环中使用它

因此,我尝试从模型实例调用eAllContents() OCL服务,即:

代码语言:javascript
复制
  ['statement1;statement2'.getDSLModel().eAllContents()/]

它实际上返回语句的列表。我不明白为什么Xtext解析器返回的Ecore实体的特性不能正常工作。

以下是Java服务,它将字符串转换为我的DSL模型(Ecore AST)的实例。我已经用一个独立的Java应用程序测试了它,它运行得很好!

代码语言:javascript
复制
 public class GetDSLModel {
 public DSLModel getDSLModel(String expression){    
    DSLStandaloneSetupGenerated dslsas = new DSLStandaloneSetupGenerated();
    Injector injector = dslsas.createInjectorAndDoEMFRegistration();
    XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
    resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
    Resource resource = resourceSet.createResource(URI.createURI("dummy:/example.dsl"));
    InputStream in = new ByteArrayInputStream(expression.getBytes());
    try {
        resource.load(in, resourceSet.getLoadOptions());
        DSLModel model = (DSLModel) resource.getContents().get(0);
        return model;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;

}

}

现在我需要主Acceleo (UML2Text)转换中的AST,因此这里是Acceleo包装器

代码语言:javascript
复制
 [query public getDSLModel(str:String): DSLModel =  (invoke('sfg.baleno.src.mloaders.GetDSLModel','getDSLModel(java.lang.String)',Sequence{str})).oclAsType(DSLModel)/]

这是我得到的如果运行它

代码语言:javascript
复制
  input: ['statement1;statement2'.getDSLModel()/]
  output: mypackage.dsl.impl.DSLModelImpl@a1c7a

  input: ['statement1;statement2'.getDSLModel().statements/]  (Syntactically VALID)
  output: invalid

  input: ['statement1;statement2'.getDSLModel().eAllContents()/]
  output: mypackage.dsl.impl.DSLStatement@e53202 (......

更新

在主Acceleo模块的Java类中,我添加了以下行

代码语言:javascript
复制
 @Override
 public void initialize(EObject element, File folder, java.util.List<? extends Object> arguments) throws IOException {    preInitialize();
    super.initialize(element, folder, arguments);
}
@Override
public void initialize(URI modelURI, File folder, java.util.List<?> arguments) throws IOException {
    preInitialize();
    super.initialize(modelURI, folder, arguments);
}

protected void preInitialize() {
   DSLStandaloneSetup.doSetup();
}

代码语言:javascript
复制
  @Override
 public void registerPackages(ResourceSet resourceSet) {
    super.registerPackages(resourceSet);
   if (!isInWorkspace(org.eclipse.uml2.uml.UMLPackage.class)) {
         resourceSet.getPackageRegistry().put(org.eclipse.uml2.uml.UMLPackage.eINSTANCE.getNsURI(), org.eclipse.uml2.uml.UMLPackage.eINSTANCE);
    }
    if (!isInWorkspace(mypackages.DSLPackage.class)) {
        resourceSet.getPackageRegistry().put(mypackages.DSLPackage.eINSTANCE.getNsURI(), mypackages.DSLPackage.eINSTANCE);
     }
   EcoreUtil.resolveAll(resourceSet);
}

但它的行为还是一样的。

更新

在这个链接中,您的临时找到一个示例EMF工作区的压缩文件,其中包含一个Acceleo和一个再现问题的XText项目。奇怪的是,如果您将它作为Java应用程序运行,它会工作,但如果您将它作为Acceleo应用程序运行,则不会.

ovo8IiZaZaXdNdFdPMTI4Yjg

在左上角,您应该找到一个文件菜单,您可以从其中下载zip文件。

EN

回答 1

Stack Overflow用户

发布于 2012-08-21 07:33:04

不幸的是我对Xtext不太熟悉..。但是我相信您的问题在于您从java服务中加载dsl的方式:您正在运行的Eclipse ("acceleo应用程序“)的上下文中生成,但是您像在独立地加载模型:新的DSLStandaloneSetup、createInjector.

我相信,这种加载模型的方式为您提供了Xtext元模型和工厂的两个实例,使得OCL在试图获取其值时无法检索特性“语句”。

我可以考虑绕过这种情况的一种可能方法是更改服务,将任何类型的EObject作为参数,并使用它的资源集来加载dsl (因此使用您在启动程序中初始化的资源集,Acceleo使用的资源集,而不是您自己的资源集):

代码语言:javascript
复制
public DSLModel getDSLModel(String expression, EObject eObj){
    ResourceSet rSet = eObj.eResource().getResourceSet();
    [...]
}

这样,您就不需要从服务中进行第二次Xtext初始化.如果它不太好用,那么除了到Xtext论坛上询问如何制作一个可以加载DSL并在独立和插件环境中工作的应用程序之外,我并没有其他的解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11966797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档