我刚接触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的范围功能有关。我查看了文档,但没有找到可以帮助我的更多内容。此外,似乎有些事情发生了变化,我遇到的例子已经过时了。
谢谢,
答案 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)
创建范围并将其返回到范围提供程序中。
您可能需要考虑缓存设备元素,而不是在询问范围提供程序时始终重新创建它们。