Silverspur
Silverspur

Reputation: 923

Why do I get a "Could not resolve reference" when I use my XText grammar?

Here is my grammar:

grammar com.x.x.x.XxxDsl with org.eclipse.xtext.common.Terminals
generate xxxDsl "http://www.x.x.x.com/xxx/xtext/XxxDsl"

Root:
    catalogs+=Catalog*
    instances+=Instance*
    ;

Catalog returns Catalog:
    'Catalog' name=ID
    '{'
    models+=Model*
    '}'
    ;

Model returns Model:
    'Model' name=ID
    ;

Instance returns Instance:
    'Instance'
    name=ID
    'of'
    model=[Model]
;

And here is my text:

Catalog myCatalog
{
    Model meteo
    Model storm
}

Instance wintermeteo of meteo
Instance strongstorm of storm

The 2 last lines are in error, meteo and storm being marked with:

Couldn't resolve reference to Model 'meteo'/'storm'

If I change my grammar so that the Models are directly in Root (and not inside Catalogs anymore) and update the text accordingly, then the models are correctly recognized.

What did I do wrong?

Upvotes: 1

Views: 665

Answers (2)

machine424
machine424

Reputation: 155

As Christian has mentioned, cross-reference relies on the attribute "name" of the element (the instance created by the rule), to avoid problems due to duplicates, the default implementation of the name provider computes a qualified name, it concatenates the name of an element (Model) with the qualified name of its container (Catalog (Christian calls it parent)) recursively (root_name.catalog_name.model_name). The "name" of "meteo" is actually "myCatalog.meteo" (the rule Root has no "name="). If you don't want to adapt the IQualifiedNameProvider (to work only with simple names), you can adapt the grammar


... model=[Model|FQN]
...
FQN: ID ("." ID)*; 

And now:

Catalog myCatalog
{
    Model meteo
    Model storm
}


Instance wintermeteo of myCatalog.meteo
Instance strongstorm of myCatalog.storm

should be accepted.

Upvotes: 1

Christian Dietrich
Christian Dietrich

Reputation: 11868

Xtext builds qualified names. So if your models have a parent with a name then the models name will be parentname.modelname

You can either adapt the IQualifiedNameProvider (subclass and bind DefaultDeclarativeQualifiedNameProvider or bind SimpleNameProvider) or you have to adapt the grammar to allow qualified names for the model reference

... model=[Model|FQN]

With

FQN: ID ("." ID)*;//pseudocode

Upvotes: 1

Related Questions