xtext 逗号分隔的变量声明

abs*_*abs 5 variables list definition xtext

我尝试根据以下语法定义一些 XText 来指定变量

variables
  MyVar1 : Bool at 0x020 value=true;
  MyVar2, MyVar3 : Int at 0x030 value 200;
end-variables
Run Code Online (Sandbox Code Playgroud)

所以每个定义在语法上都是

VarName ["," VarName]* ":" Type ["at" HEX]? ["value" VALUE]? ";"
Run Code Online (Sandbox Code Playgroud)

所有变量都应可通过其引用进行访问,大纲中的结果应如下所示:

variables
+-MyVar1 : Bool
+-MyVar2 : Int
+-MyVar3 : Int
Run Code Online (Sandbox Code Playgroud)

编辑: 按照这里的要求,我的实际语法,相当于上面几行的语法定义。

Variable:
  name=ID
;
Declaration_Var:
  'variables'
  vars+=Declaration_Var_Body+
  'end-variables' ';'
;
Declaration_Var_Body:
  varDecl+=Variable(',' varDecl +=Variable)*
  ':' type=[TR_Any]
  ('at' address=HEX)?
;
TR_Any:
  ...
;
terminal HEX:
  ...
;
Run Code Online (Sandbox Code Playgroud)

这样,以下字符序列

variables
  Test1, Test2, Test3 : DWORD at 0x20;
end_var;
Run Code Online (Sandbox Code Playgroud)

结果是这样的:

<unnamed>
+-- 0x20
|   +-- Test1
|   +-- Test2
|   +-- Test3
Run Code Online (Sandbox Code Playgroud)

这几乎与我的预期相反。我期望的和我想要在大纲中生成的内容与此类似(数据类型和地址不得显示在那里,但至少它们必须可以作为变量声明的生成类的属性进行访问)

Test1
+-- DWORD
+-- 0x20
Test2
+-- DWORD
+-- 0x20
Test3
+-- DWORD
+-- 0x20
Run Code Online (Sandbox Code Playgroud)

Bor*_*ski 4

请在此处查看涵盖您的案例的截屏视频:http://xtextcasts.org/episodes/18-model-optimization

您需要修改模型和元模型。要修改元模型,您需要定义一个后处理器。以下后处理器将type属性目录添加到Variable类中。

有关更多详细信息,请参阅:http://christiandietrich.wordpress.com/tag/postprocessor/

class MyXtext2EcorePostProcessor implements IXtext2EcorePostProcessor {
  override process(GeneratedMetamodel metamodel) {
    metamodel.EPackage.process
  }

  def process(EPackage p) {
    for (clazz : p.EClassifiers.filter(typeof(EClass))) {
      if (clazz.name == typeof(Variable).simpleName) {
        val typeAttribute = EcoreFactory::eINSTANCE.createEAttribute
        typeAttribute.name = "type"
        typeAttribute.EType = EcorePackage::eINSTANCE.EString
        clazz.EStructuralFeatures += typeAttribute
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你必须Generator像这样绑定它扩展:

public class ExtendedGenerator extends Generator {
  public ExtendedGenerator() {
    new XtextStandaloneSetup() {
      @Override
      public Injector createInjector() {
        return Guice.createInjector(new XtextRuntimeModule() {
          @Override
          public Class<? extends IXtext2EcorePostProcessor>
                                 bindIXtext2EcorePostProcessor() {
            return MyXtext2EcorePostProcessor.class;
          }
        });
      }
    }.createInjectorAndDoEMFRegistration();
  }
}
Run Code Online (Sandbox Code Playgroud)

最后ExtendedGenerator在您的 mwe2 工作流程中使用新的:

... 
Workflow {
  ...
  bean = StandaloneSetup {
    ...
    component = postprocessor.ExtendedGenerator { // Set ExtendedGenerator!
      ...
    }
    ...
  }
  ...
}
...
Run Code Online (Sandbox Code Playgroud)

然后你必须type用数据填充你的新属性。您可以通过实现IDerivedStateComputer接口来做到这一点。

class MyDerivedStateComputer implements IDerivedStateComputer {

  override discardDerivedState(DerivedStateAwareResource resource) {
    resource.allContents.filter(typeof(VariableDefinition)).forEach [
      type = null
    ]
  }

  override installDerivedState(DerivedStateAwareResource resource,
                               boolean preLinkingPhase) {
    resource.allContents.filter(typeof(VariableDefinition)).forEach [
      type = (eContainer as DefinitionBlock).type
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你必须像这样绑定它(第二个和第三个绑定方法仅对于非 Xbase 项目是必需的)

public class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
  public Class<? extends IDerivedStateComputer> bindIDerivedStateComputer() {
    return MyDerivedStateComputer.class;
  }

  // Not needed for Xbase-projects
  @Override
  public Class<? extends XtextResource> bindXtextResource() {
    return DerivedStateAwareResource.class;
  }

  // Not needed for Xbase-projects
  public Class<? extends IResourceDescription.Manager>
                         bindIResourceDescriptionManager() {
    return DerivedStateAwareResourceDescriptionManager.class;
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以更进一步,即时重组模型以满足您的需求。如果您走得太远,请将您的解决方案作为单独的答案发布在这里。