2013-03-14 83 views
4

我嘗試定義一些XTEXT爲specifiying變量按照以下語法XTEXT逗號分隔的變量聲明

variables 
    MyVar1 : Bool at 0x020 value=true; 
    MyVar2, MyVar3 : Int at 0x030 value 200; 
end-variables 

因此,每個定義是語法

VarName ["," VarName]* ":" Type ["at" HEX]? ["value" VALUE]? ";" 

所有變量應以他們的參考和訪問導致大綱應該是這樣的:

variables 
+-MyVar1 : Bool 
+-MyVar2 : Int 
+-MyVar3 : Int 

編輯: 這裏要求我的實際語法,這相當於上面的一些語句的語法定義。

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: 
    ... 
; 

有了這個,以下字符

variables 
    Test1, Test2, Test3 : DWORD at 0x20; 
end_var; 

導致的輪廓是這樣的順序:

<unnamed> 
+-- 0x20 
| +-- Test1 
| +-- Test2 
| +-- Test3 

這幾乎是與我期望的相反。我所期望的以及我想要在大綱中生成的內容與此類似(數據類型和地址不能在那裏顯示,但至少它們必須可以作爲生成的變量聲明類的屬性訪問)

Test1 
+-- DWORD 
+-- 0x20 
Test2 
+-- DWORD 
+-- 0x20 
Test3 
+-- DWORD 
+-- 0x20 
+0

請問您可以發表您當前的語法並提出具體問題嗎? – 2013-03-15 15:24:46

+0

我在那裏添加了一些更詳細的描述 – abs 2013-03-18 18:07:46

+0

好吧,現在我明白你的問題了。你實際上只是對看起來很漂亮的輪廓感興趣,或者是以你描述的方式修改內部結構嗎? – 2013-03-19 10:44:03

回答

1

查看涵蓋您的案例的屏幕錄像: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 
     } 
    } 
    } 
} 

然後,你必須把它綁定擴展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(); 
    } 
} 

最後使用新ExtendedGenerator在mwe2的工作流程:

... 
Workflow { 
    ... 
    bean = StandaloneSetup { 
    ... 
    component = postprocessor.ExtendedGenerator { // Set ExtendedGenerator! 
     ... 
    } 
    ... 
    } 
    ... 
} 
... 

然後你必須填寫你的新的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 
    ] 
    } 
} 

然後,你必須綁定它像這樣(第二和第三結合的方法僅適用於非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; 
    } 
} 

你可以再進一步,重組對你的模型飛行以滿足您的需求。請在這裏發佈您的解決方案作爲一個單獨的答案,以防你走得那麼遠。

+0

不完全是我在找什麼。在您的語法中,可以指定一個變量列表,如 'MyVar1:MyType,MyVar2:MyType,...' 我需要像這樣指定它們: 'MyVar1,MyVar2,...:MyType'(請參見語法定義在問題中) – abs 2013-03-18 18:11:24