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) エディターが 'extends' 句でオートコンプリートしないこと、および (2) エディターがエラー メッセージを表示することですCouldn't resolve reference to Release '1.2.3'

私は何が欠けていますか?

4

2 に答える 2

2

QualifiedNameProvider は、偽の修飾名を作成しているようです。たとえば、リリース 1.2.2 の名前には、ルックアップが [release][1][2][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 に答える