I know there is a simple solution for this but I have no idea how to implement it.
I'm looking for how to implement the answer rather than what I need to do. Half the answer is already on this page: Xtext cross referencing and scoping
My problem is with the grammar below:
DomainModel:
"DOMAINMODEL" name=ID "{"
"ENTITYS" "{"
(Entitys+=Entity)*
"}"
"ENTITY_RELATIONSHIP" "{"
(Relationships+=Relationship)*
"}"
"}";
Entity:
name=ID "{"
(Attributes+=Attribute)*
"}";
Attribute:
StringAttribute | NumberAttribute | ImageAttribute;
StringAttribute:
"STRING" name=ID;
NumberAttribute:
"NUMBER" name=ID;
ImageAttribute:
"IMAGE" name=ID;
// Relationship = [new table name] : [shared key name] -> ref_table(ref_id)
Relationship:
name=ID ":" newEntityName=ID "->" refEntityName=[Entity|ID]"("refName=[Attribute|ID]")"; // <- Problem here
When I write the model, I cannot get the "refName=[Attribute|ID]" to reference to attributes inside an entity. In the code below
DOMAINMODEL auctionHouse{
ENTITYS {
lots{
NUMBER id0
NUMBER lotNo
STRING name
STRING priceEstimate
STRING description
}
auctions{
NUMBER id1
NUMBER date
STRING description
}
auction_lots{
NUMBER id2
STRING lot_id
NUMBER auction_id
}
}
ENTITY_RELATIONSHIP {
auction_lots : lot_id -> lots(id0) // <- Will not find 'id0'
auction_lots : auction_id -> auctions(id1) // <- Will not find 'id1'
}
}
How can I widen the scope? How can I differentiate between two attributes with the same name but in different scopes?
The problem with the references is that they simply cannot be found in that scope, what you could do is introduce a qualified name and use that in your cross-reference and change your grammar accordingly, ie:-
QualifiedName:
ID ('.' ID)*;
Relationship:
name=ID ":" newEntityName=ID "->" refName=[Attribute|QualifiedName];
Now it should be possible to reference by using the qualified ID:
ENTITY_RELATIONSHIP {
auction_lots : lot_id -> auctionHouse.lots.id0
auction_lots : auction_id -> auctionHouse.auctions.id1
}
If you can't change the grammar like this to make use of the default way Xtext handles names then you would need to look into providing your own qualified names, a great article for that is this Qualified Names Article