On this page we look at some examples of how the meta-model is generated from the grammar. In the first example we look at the default example.
Here each rule in the grammar created an EClass in the metemodel.
grammar | meta-model |
---|---|
Model: greetings+=Greeting*; Greeting: 'Hello' name=ID '!'; |
However there is not always a 1:1 relationship between rules and EClasses.
Terminals do not generate EClasses.
Superclasses
In the following case Greeting is a superclass of Greeting2
grammar | meta-model |
---|---|
Model: greetings+=Greeting*; Greeting: 'Hello' Greeting2; Greeting2: name=ID '!'; |
Datatype Rules
Datatype rules are rules that do not:
- call other parser rules
- contain any actions
- contain assignments
In the following example 'Greeting' and 'Greeting2' contain only terminals with no assignment so there is not an EClass for these rules. We have a visual indication of this in the grammar because it is shown in blue.
grammar | meta-model |
---|---|
Model: greetings+=Greeting*; Greeting: Greeting2; Greeting2: 'Hello' ID '!'; |
Recursion
We can use a rule inside itself, or call another rule which calls this rule, but there are limitations on this. We cannot use left-recursion which means we must consume a token before looping back.
Here is a first attempt at a recursive grammar:
grammar | meta-model |
---|---|
Model: greetings+=Greeting*; Greeting: Greeting2; Greeting2: '(' Greeting2 ')'; |
However this is not going to work because the recursion is just a datatype rule so it won't generate any code. So if we try to run the editor in a new instance of Eclipse we get:
"An internal error occurred during: "XtextReconcilerJob".
java.lang.StackOverflowError"
I therefore added an assignment 'n=' here:
grammar | meta-model |
---|---|
Model: greetings+=Greeting*; Greeting: Greeting2; Greeting2: '(' n=Greeting2 ')'; |
However when we run the editor we still get: java.lang.StackOverflowError because all we can do is add parenthasis and each parenthasis requires another below it.
So I have made the recursion optional by adding '?' here:
grammar | meta-model |
---|---|
Model: greetings+=Greeting*; Greeting: Greeting2; Greeting2: {Greeting2} '(' n=Greeting2? ')'; |
This generated a warning message becase the rule Greeting2 might not be created so I also added an action: {Greeting2}
grammar | meta-model |
---|---|
grammar | meta-model |
---|---|
grammar | meta-model |
---|---|
grammar | meta-model |
---|---|