When we were discussing Qualified Names on this page we saw that there is a built-in containment relationship between the objects in a model. However we sometimes need to represent a relationship between objects which is not a containment relationship (so if the object holding the relationship is deleted the object that it is pointing to does not disapear - there is no 'ownership'). |
These links are made using some string to represent the object.
In the xtext grammar square brackets represent this type of cross reference, that is a non-containment reference.
Syntax Element | Means |
---|---|
[t|n] | cross reference to an (already existing) object of type' t' via a name that has the syntax of 'n' |
Where:
- t=ReferencedEClass: type of referenced object
(not grammar rule but an EClass ) - n=CrossReferenceTerminal: string returning grammar rule.
Used to cross reference to referenced object.
If the CrossReferenceTerminal is not explicitly included then it will default to ID, that is, [Type] is a shorthand for [Type|ID]
Example
This is taken from 15min tutorial here.
We want one entity to extend another.
entity HasAuthor { author: String } entity Post extends HasAuthor { title: String content: String many comments: Comment } |
This is a non-containment reference, so we use a cross reference in the grammar like this:
Entity : 'entity' name = ID ('extends' superType = [Entity | QualifiedName])? '{' features += Feature* '}' ; |
Another Example
Here is another example, cut down to its essentials to illustrate some points. The grammar is shown below: |
|
grammar com.euclideanspace.naming.Example with org.eclipse.xtext.common.Terminals generate example "https://www.euclideanspace.com/naming/Example" Model: a+=A*; A: 'a' name=ID ('{' b+=B* c+=C* '}')?; B: 'b' name=ID; C: 'c' name=[B|ID]; |
|
When we start this program up in a new instance of eclipse we can see that the cross-link gives an error unless it links to an instance of B within the same A. | |
a tom a dick a tom2 a dick2 {b harry c tom} a tom3 {b harry b tom} |
|
This gave the error: Couldn't resolve reference to B 'tom' If we changed the 4th line to a dick2 {b harry c harry} This code also generated runtime error messages, indicating that we need to change some of the code: |