2016-04-26 15 views
0

私はXtextとXtendで作業するのが初めてで、誰かが私の解決に役立つことを願っている問題を見つけました。 私が達成しようとしているのは、DSLで明示的に宣言するのではなく、外部ソースから変数を解決することです。 私は証明するために、次の例を得た:ここ は文法です:私のDSLの変数を外部ソースから解決する

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.xbase.Xbase 

generate myDsl "http://www.xtext.org/example/mydsl/MyDsl" 

Model: 
configUrl=ConfigUrl 
devices+=Device* 
test=Test 
; 

ConfigUrl: 
"ConfigURL=" url=STRING 
; 

Device: 
'Device' name=ID 
'has channels: ' (channels+=Channel (',' channels+=Channel)*)? 
; 

Channel: 
name=ID 
; 

Test: 
'DoSomething' channel=[Channel|QualifiedName] 
; 

、ここでは使用例です:

ConfigURL="http://localhost:8080/devices" 
Device Light has channels: state 
DoSomething Light.state 

代わりに明示的に私が解決したいDSLのデバイスを宣言する外部ソース(ConfigURL変数)からのものです。私が知る限り、私が探しているのはXtendのスコープ機能に関係しています。私はドキュメンテーションを見てきましたが、それ以上私を助けてくれるものはほとんど見つかりませんでした。また、いくつかのことが変わってきていると思われ、私が見た例は時代遅れです。

おかげで、

答えて

0

あなたの要素は、例えば、あなたがそれらを作成する必要がありますXTEXTによって解析されませんので、スコーププロバイダ内のこのためには、まず、デバイスクラスとチャネルクラスを記述するecoreモデルを作成します。これらの要素にDSL内の参照が必要です(例:

DeviceDesc: 
    'Device' deviceRef=[Device|ID] 
    'has channels: ' (channels+=[Channel] (',' channels+=[Channel])*)?; 

次に、あなたが実装独自のスコーププロバイダが必要です。

をあなたがURLを解決する必要があり、この方法では。

String url = ((Model)context.eContainer()).getConfigUrl(); 

URLを使用して外部データを取得し、そこからデバイス要素を作成します。その後、Scopes.scopeFor(myDeviceList)を使用してスコープを作成し、スコーププロバイダに返します。

スコーププロバイダに尋ねられたときにデバイスの要素を常に再作成するのではなく、キャッシングすることを検討するとよいでしょう。