Eclipse Xtext Grammar to Model Examples

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 '!';
metamodel1

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 '!';
metamodel2

Datatype Rules

Datatype rules are rules that do not:

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 '!';
metamodel3

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 ')';
metamodel4

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 ')';
metamodel

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? ')';
metamodel

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
 

 

 


metadata block
see also:

More on ECore here and on the Lars Vogel site here.

Correspondence about this page

This site may have errors. Don't use for critical systems.

Copyright (c) 1998-2023 Martin John Baker - All rights reserved - privacy policy.