Xtext 中的作用域

Scoping in Xtext

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

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 class 并重写它:

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

您正在使用交叉引用作为 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)*;

或者也可能删除花括号(但您稍后可能需要嵌套块,在这种情况下您可能需要它们)。只有你知道,但它值得考虑。