我很难理解如何影响范围界定。 假设我有简单的语法:
Model:
def = DefVarList
(use = UseList)?
;
DefVarList:
name = 'def' '{' (list += DefVar)* '}'
;
DefVar:
name = ID ';'
;
UseList:
name = 'use' '{'
(list += UseVar)*
'}'
;
UseVar:
name = [DefVar] ';'
;
当然,写一些像
的东西def { qwerty; }
use { qwerty; }
结果错误,因为无法解析引用。所以我去了ScopeProvider类并重写它:
public class TestgrammarScopeProvider extends AbstractTestgrammarScopeProvider{
public IScope scope_UseVar_name(UseVar v, EReference ref) {
Model m = (Model)v.eContainer().eContainer();
return Scopes.scopeFor(m.getDef().getList());
}
}
这不起作用。它甚至没有调用此函数。我做错了什么?
P.S。我知道在我的mwe2文件中插入片段行,但我想知道为什么这个程序不会调用这个函数。
答案 0 :(得分:0)
您在UseVar中使用交叉引用作为标识符。我改变了
UseVar: ref=[DefVar] ';'
然后这个xtend片段适用于您的DSL。
override IScope getScope(EObject context, EReference ref){
if(context instanceof UseVar && ref == USE_VAR__REF){
val model = context.getContainerOfType(Model)
val defVarList = model.def.list
return Scopes::scopeFor(defVarList)
}
return IScope::NULLSCOPE
}
我还假设这只是一个启动你的项目的开始演示,但你可能会考虑删除一些语法噪音,比如用这个来代替
List items+=rule (',' items+=rule)*;
或者也许删除花括号(但是你可能想要嵌套块,在这种情况下你可能需要它们)。只有你可以说,但值得考虑。