从外部来源解析我的DSL中的变量

时间:2016-04-26 09:25:13

标签: xtext xtend

我刚接触Xtext和Xtend,我偶然发现了一个问题,我希望有人可以帮我解决。 我想要实现的是从外部源解析变量,而不是在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的范围功能有关。我查看了文档,但没有找到可以帮助我的更多内容。此外,似乎有些事情发生了变化,我遇到的例子已经过时了。

谢谢,

1 个答案:

答案 0 :(得分:0)

由于您的元素未被xtext解析,因此您需要创建它们,例如:在范围提供者中。为此,首先创建一个描述Device和Channel类的ecore模型。您还需要在DSL中引用这些元素,例如

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

然后你需要一个自己的范围提供者来实现:

public IScope scope_DeviceDesc_deviceRef(final DeviceDesc context, EReference reference)

在此方法中,您需要解析URL。您可以通过上下文元素获取它:

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

使用URL检索外部数据并从中创建设备元素。然后使用Scopes.scopeFor(myDeviceList)创建范围并将其返回到范围提供程序中。

您可能需要考虑缓存设备元素,而不是在询问范围提供程序时始终重新创建它们。