在Xtext中确定范围

时间:2016-05-20 08:04:39

标签: xtext scoping

我很难理解如何影响范围界定。 假设我有简单的语法:

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文件中插入片段行,但我想知道为什么这个程序不会调用这个函数。

1 个答案:

答案 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)*;

或者也许删除花括号(但是你可能想要嵌套块,在这种情况下你可能需要它们)。只有你可以说,但值得考虑。