2017-01-31 15 views
0

由於討論中已創建了一個工作示例並將其添加到https://github.com/Johanvdberg/mcrl2.xtext,請參閱test.multiname。*和test.reflang。* eclipse項目。從另一個DSl及其型號引用DSL

Multiname由語法定義

grammar test.multiname.dsl.MultiNameDsl with org.eclipse.xtext.common.Terminals 

generate multiNameDsl "http://www.multiname.test/dsl/MultiNameDsl" 

Model: 
    modules+=Module+; 

Module: 
    'begin module' name=ID 
    vars+=Vars* 
    funcs+=Funcs* 
    'end_module'; 

VarName: 
    name=ID; 

FuncName: 
    name=ID; 

Name: 
    VarName | FuncName; 

Funcs: 
    'func' left=FuncName (bracket?='(' ')')? '=' right=[Name] ';'; 

Vars: 
    'var' VarName ';'; 

文件與此語法看起來像

begin module test1 
var t1v1; 
var t1v2; 
end_module 

begin module test2 
var t2v1; 
var t2v2; 
end_module 

語言的語法,將參考以上語言,RefLang

與org.eclipse.xtext.common.Terminals

generate refDsl "http://www.reflang.test/dsl/RefDsl" 
import "http://www.multiname.test/dsl/MultiNameDsl" as multi 

Model: 
    ref_from=Import 
    refs=DataRef; 

Import: 
    'import' imports=[multi::Module]; 

DataRef: 
    'ref_vars' data+=[multi::VarName|FQN] (',' data+=[multi::VarName|FQN])*; 

FQN: 
    ID ("." ID)*; 

,並與上面的語法文件語法test.reflang.dsl.RefDsl樣子:

import test2 
ref_vars test2.t2v1, test1.t1v1 

的願望行爲是ref_vars只能從import指定的模塊中,在上面的文件中是test2和var test1.t1v1是不正確的。

RefLang範圍提供商是:

override getScope(EObject context, EReference reference) { 
    if (context instanceof DataRef) { 
     if (reference == RefDslPackage.Literals.DATA_REF__DATA) { 
      val rootElement = EcoreUtil2.getRootContainer(context) 
      return super.getScope(context, reference); 
     } 
    } 
    return super.getScope(context, reference); 
} 

但我無法通過使用rootElement的訪問從RefLangmultiname語言和參考定義的模型元素test2。所有的屬性rootElement.ref_from.imports.{vars, funcs}null

注意被質疑的改變了一下和這個工作,這些改變是基於對舊問題的評論作出的。

老問題 我有兩個語法AB其中從語法A語法B參考要素:

Model: 
    import_model=Import 
    flows=FlowData; 

Import : 
    'import' importURI=STRING ';'; 


FlowData: 
    'flows' data+=[A::Flow|FQN] (',' data+=[A::Flow|FQN])* ';'; 

FQN: ID ("." ID)*; 

importURI定義使用語法A文件和包含的Flow定義開始引用。

使用如https://christiandietrich.wordpress.com/2011/10/15/xtext-calling-the-generator-from-a-context-menu/中的上下文菜單,可以訪問語法B的模型。 importURI指定的文件模型如何在同一個處理程序中訪問?

更新1

除了與進口的MWE2文件:在語法文件

fragment = scoping.ImportNamespacesScopingFragment2 auto-inject {} 
referencedResource="platform:/resource/.../A.genmodel" 

語法B的DSL項目的plugin.xml

import "http://www..../A" as A 

依賴關係增加了語法A的dsl項目。 ide和ui項目對ide和ui的依賴也分別增加了。

語法A的完整模型需要訪問。語法A定義系統和語法B定義數據在系統中的位置,並且需要轉換兩個模型的並集。

一個以上的配置(模型)可能存在的語法A的每個模型。

+0

它實際上不能(直接地)進口的進口,而不是參考。簡單地遵循流程參考是否足夠,還是需要關注未使用的進口?您是否設置了正確的範圍來使用舊的導入Uri語法?請詳細說明 –

+0

請參閱更新1 – Johan

+0

如果您使用導入的基於範圍的名稱,則不使用導入Uri。還有一個問題:是關於導入Uri的問題(數據引用在編輯器中不起作用),還是關於跟蹤數據引用或關於如何將未使用的importUri文件加載到某處在處理程序 –

回答

1

你似乎是個男的,在語法

Funcs: 
'func' left=FuncName (bracket?='(' ')')? '=' right=[Name] ';'; 

Vars: 
'var' varName=VarName ';'; 

這裏真的帽子的任務是,對我

class MyDslScopeProvider extends AbstractMyDslScopeProvider { 

    override getScope(EObject context, EReference reference) { 
     if (context instanceof DataRef) { 
      if (reference == MyDslPackage.Literals.DATA_REF__DATA) { 
       val rootElement = EcoreUtil2.getContainerOfType(context, Model) 
       val names = <Name>newArrayList 
       val importedModule = rootElement?.ref_from?.imports 
       if (importedModule !== null) { 
        for (v : importedModule.vars.map[varName]) { 
         names += v 
        } 
        for (f : importedModule.funcs.map[left]) { 
         names += f 
        } 
       } 
       // this is the unqualified variant 
       // return Scopes.scopeFor(names) 
       // this is the unqualified variant 
       return Scopes.scopeFor(names, [QualifiedName.create(importedModule.name, it.name)], IScope.NULLSCOPE) 
      } 
     } 
     return super.getScope(context, reference); 
    } 

} 

此外,在關鍵字空間使用正常工作的scopeprovider是代碼味道和可能會導致意外的行爲

,你應該考慮只爲引用 (在作用域簡單薩姆斯 - 看我的意見 - 一個ND在語法ref=[XXX|ID]

+0

空間是一個錯字,空間應該是'_'。 ''''rootElement?.ref_from?中的'?'做了什麼?在聲明執行之後,會填充前面的'null'字段。 – Johan

+0

?只是一個無效安全性 x?.y。?z如果x爲null或y爲null或z爲null,但不包含NullPointerException –