Chapter 3. Define the metamodel

The first step of this tutorial is to define the abstract syntax. To do so, we have to define the main concepts. For the logo language, these concepts are the instructions to be executed : pen up, pen down, go forward, rotate left ...

[Tip]Tip

If you want to learn more about how to create an ecore metamodel with eclipse, please follow the how-to in the next sections or refer to the other available tutorial

3.1. From Ecore to genenerated code

In order to define the metamodel, we are going to process as shown in the following steps : create an ecore file, set up its nsURI and create its corresponding generator model (.genmodel). Then, we are going to set up the needed informations (base package, model directory, file extension, plugin ID,...) :

  1. Inside the project org.kermeta.kmlogo.logoasm.tutorial, open ther folder parts/1.metamodel and open the file ASMLogo.ecore which is the metamodel of your language (here logo) and look at its content. In this ecore file you'll notice the various instructions supported by the DSL that we are going to build. Some are primitives, for example : Back, Forward, Left, PenUp, ... Some are expressions, for example : Plus, Minus, ... And some are control structures, for example : If, while, Repeat, ...

  2. If not already set in the property view, do not forget to set the properties of our metamodel like in this example :

    1. Inside the file ASMLogo.ecore;

    2. Select kmLogo package, right-click on it and choose show properties view;

    3. Set the ns URI to "http://www.kermeta.org/kmLogo" and save it;

    Example 3.1. Set up nsURI


  3. Then, we need to create the generator model for this ecore. For those who are familiar with creating a genmodel, we've provided a completed one inside the folder parts/1.metamodel (see the file ASMLogo.genmodel) so that you can rapidly jump to the next step. For the begginers, below is a step by step guide to create one.

    create an EMF Generator Model (File > New..) and name it ASMLogo.genmodel, hit next and chosse Ecore model as model importers, hit next and import the previous metamodel (Browse workspace > org.kermeta.kmlogo.logoasm.tutorial/1.metamodel), load it, hit next and finish. In the example below, you can set up the properties for code generation, if needed you can manually tweak them but normally you should leave them as they are auto-generated (you should result in a file with the same inforamtions as the provided ASMLogo.genmodel).

    1. Open the file ASMLogo.genmodel;

    2. Unfold the root element ASMLogo and select the kmLogo package;

    3. Right-click on it and choose show properties View (if not already open), set the base package (unfold All in property view) property to : org.kermeta.kmlogo.logoasm.model;

    4. For the ASM package (unfold kmLogo package) set its File Extension (unfold Model in the property view) property to "logoasm";

    5. Right-click on the root element ASMLogo and choose show properties View (if not already open);

    6. In the property view, unfold Model:

      • Set "Model Directory" to /org.kermeta.kmlogo.logoasm.model/src

      • Set "Model Plug-in ID" to org.kermeta.kmlogo.logoasm.model

    7. In the property view, unfold Edit:

      • Set "Edit Directory" to /org.kermeta.kmlogo.logoasm.edit/src

      • Set "Edit Plug-in Class" to org.kermeta.kmlogo.logoasm.kmLogo.provider.ASMLogoEditPlugin

      • Set "Edit plug-in ID" to org.kermeta.kmlogo.logoasm.edit

    8. In the property view, unfold Editor:

      • Set "Editor Directory" to /org.kermeta.kmlogo.logoasm.editor/src

      • Set "Editor Plug-in Class" to org.kermeta.kmlogo.logoasm.kmLogo.presentation.ASMLogoEditorPlugin

      • Set "Editor plug-in ID" to org.kermeta.kmlogo.logoasm.editor

    Example 3.2. Manually set properties of a .genmodel


  4. If you have manually set up the properties, do not forget to save your generator model. Let's directly generate the associated code for our metamodel. Remember the main concepts of our DSL that we've mentioned before, this is step is mandatory as it gives a first implementation of our DSL with EMF :

    Inside the ASMLogo.genmodel, right-click on kmLogo package and choose Generate Model Code. This will add a new project org.kermeta.kmlogo.logoasm.model to your structure.

    Repeat the step above and choose Generate Edit code. This will add a new project org.kermeta.kmlogo.logoasm.model.edit to your structure.

    Repeat again and choose Generate Editor Code. This will add the project org.kermeta.kmlogo.logoasm.model.editor.

    Copy the files ASMLogo.ecore and ASMLogo.genmodel inside a folder org.kermeta.kmlogo.logoasm.model/model in order to be coherent with the plugin intention (store the model and the model code)

    You should now have a project structure as illustrated below :

    Project structure after generating the model, edit and editor code

    Figure 3.1. Project structure after generating the model, edit and editor code


  5. To have an overview of our DSL, go back to the file org.kermeta.kmlogo.logoasm.model/model/ASMLogo.ecore:

    Right-click on it and initialize the ecore diagram file.

    Name it ASMLogo.ecorediag, hit next and choose ASM package as a root element and finish to see the graphical representation of your metamodel (if you choose kmLogo as a root element then you will have to double-click on Package ASM to open it and then Create button from the window wizard).

    You should obtain an overview of all the concepts in your metamodel (see the figure below -it may differ from actual version but is here for illustration purpose).

The logo metamodel

Figure 3.2. The logo metamodel


[Important]Important

Before going further in this tutorial, do not forget (if not already done) :

  • To set up the nsURI of the model/ASMLogo.ecore file;

  • To register this ecore model (In deployed mode (ie. in a runtime workbench), the ecore is automatically registered by the plugin, in development mode, you need to manually register it).

3.2. Metamodel Ecore with Kermeta

Many ecore tools allow you to create your metamodel. Kermeta allows you to do it in a "programmatical" way. Analyse the content of the listing below and see what does it stand for :

@uri "http://www.kermeta.org/kmLogo"
package kmLogo;

require "kermeta"
alias Integer : kermeta::standard::Integer;
alias Boolean : kermeta::standard::Boolean;
alias String : kermeta::standard::String;
package ASM
{
	abstract class Instruction
	{
	}
	abstract class Primitive inherits Instruction
	{
	}
	class Back inherits Primitive
	{
		attribute steps : Expression[1..1]

	}
	class Forward inherits Primitive
	{
		attribute steps : Expression[1..1]

	}
	class Left inherits Primitive
	{
		attribute angle : Expression

	}
	class Right inherits Primitive
	{
		attribute angle : Expression

	}
	class PenDown inherits Primitive
	{
	}
	class PenUp inherits Primitive
	{
	}
	class Clear inherits Primitive
	{
	}
	abstract class Expression inherits Instruction
	{
	}
	abstract class BinaryExp inherits Expression
	{
		attribute lhs : Expression[1..1]

		attribute rhs : Expression[1..1]

	}
	class Constant inherits Expression
	{
		attribute integerValue : Integer

	}
	class ProcCall inherits Expression
	{
		attribute actualArgs : Expression[0..*]

		reference declaration : ProcDeclaration[1..1]#procCall

	}
	class ProcDeclaration inherits Instruction
	{
		attribute name : String

		attribute args : Parameter[0..*]

		attribute block : Block

		reference procCall : ProcCall[0..*]#declaration

	}
	class Block inherits Instruction
	{
		attribute instructions : Instruction[0..*]

	}
	class If inherits ControlStructure
	{
		attribute thenPart : Block[1..1]

		attribute elsePart : Block

	}
	class ControlStructure inherits Instruction
	{
		attribute condition : Expression

	}
	class Repeat inherits ControlStructure
	{
		attribute block : Block[1..1]

	}
	class While inherits ControlStructure
	{
		attribute block : Block[1..1]

	}
	class Parameter
	{
		attribute name : String

	}
	class ParameterCall inherits Expression
	{
		reference parameter : Parameter[1..1]

	}
	class Plus inherits BinaryExp
	{
	}
	class Minus inherits BinaryExp
	{
	}
	class Mult inherits BinaryExp
	{
	}
	class Div inherits BinaryExp
	{
	}
	class Equals inherits BinaryExp
	{
	}
	class Greater inherits BinaryExp
	{
	}
	class Lower inherits BinaryExp
	{
	}
	class LogoProgram
	{
		attribute instructions : Instruction[0..*]

	}
}

Inside org.kermeta.kmlogo.logoasm.model/model, create a new folder srcKermeta.

Inside this newly created folder, create a new Kermeta file (.kmt) and type the listing above inside (to save time, after analysing the listing above, you may copy/paste to replace the generated code).

After saving, right-click on it and choose Kermeta > Generate Ecore.

You should retrieve our logo language's .ecore representation that we 've just seen before. Congratulation you've just "written" your first kermeta program of this tutorial, and you have define the famous main concepts of your DSL!