3

我正在尝试让交叉引用在我的 DSL 中工作。这是语法的精简版本(标准示例 DSL 的修改版本):

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"

Releases:
    releases+=Release*
;

terminal VERSION    : ('0'..'9')+'.'('0'..'9')+('.'('0'..'9'|'x')+)?;

Release:
    'release' version = VERSION ('extends' parent = [Release|VERSION])?
    ;

由于我没有使用标准name = ID模式,因此我关注了这篇关于如何创建自己的博客文章IQualifiedNameProvider

public class MyDslQNP extends DefaultDeclarativeQualifiedNameProvider {
    QualifiedName qualifiedName(Release e) {
        Package p = (Package) e.eContainer();
        return QualifiedName.create(p.getName(), e.getVersion());
    }
}

从关于 SO 的另一个答案中,我收集到我应该实现自己的范围提供程序:

public class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
    IScope scope_Release_parent(Release release, EReference ref) {
        Releases releases = (Releases) release.eContainer();
        return Scopes.scopeFor(releases.getReleases());
    }
}

我还在运行时模块中绑定了这些:

public class MyDslRuntimeModule extends
        org.xtext.example.mydsl.AbstractMyDslRuntimeModule {
    @Override
    public Class<? extends IQualifiedNameProvider> bindIQualifiedNameProvider() {
        return MyDslQNP.class;
    }

    @Override
    public Class<? extends IScopeProvider> bindIScopeProvider() {
        return MyDslScopeProvider.class;
    }

}

运行生成的编辑器时,我创建了一个如下所示的文件:

release 1.2.3
release 1.2.2 extends 1.2.3

问题是(1)编辑器不会自动完成“扩展”子句,(2)编辑器显示错误消息Couldn't resolve reference to Release '1.2.3'

我错过了什么?

4

2 回答 2

2

您的 QualifiedNameProvider 似乎创建了虚假的限定名称,例如版本 1.2.2 的名称将有两个段 [release][1.2.2],其中查找将搜索 [release][1][2][2]。

请尝试创建一个适当的限定名称,如下所示:

QualifiedName qualifiedName(Release e) {
    Package p = (Package) e.eContainer();
    QualifiedName release = getConverter().toQualifiedName(e.getVersion());
    return QualifiedName.create(pack.getName()).append(releaseSuffix);        
}
于 2012-04-26T10:03:00.923 回答
1

Scopes.scopeFor 是一个静态方法,因此不使用配置的 IQualifiedNameProvider。您需要使用 Scopes.scopeFor(Iterable, Function, IScope) 显式传递它

但是在您的情况下,您根本不需要在范围提供程序中进行特殊处理,因为具有限定名称提供程序的本地元素会自动放在范围内。

于 2012-04-25T18:53:52.950 回答