Tuesday 12 July 2011

Xtext 2.0 Mixin How-To

Last Week I've been experimenting with Xtext 2.0 and wanted to have a Mixin of two DSLs (one DSL referencing model elements of another DSL). I've done something similar about 8 months ago using XText 1.0 and of course by now I've completely forgotten the gory details and frustration levels involved in figuring out how to do it.

I was hoping that by now there would be some "how-to" available online; but Google search hasn't come up with anything useful. Hence, here is a short description of how a Mixin can be done:

So, what is a Mixin? Assume that you have two Xtext grammars: A and B. As long as A and B are independent of each other, you don't need Mixins. Now, let's assume that grammar A references elements that are described in grammar B or simply extends grammar B. In that case you need to tell grammar A about grammar B.

If you consult the Xtext documentation you won't get very far. To correct that here is what you need to do:

  1. Create Xtext projects for both grammar A and grammar B (you probably already did this)
  2. Add a plug-in dependency of A's Xtext project to B's Xtext project
  3. Edit the A.xtext file to include the following statement:
    import "platform:/resource/B/src-gen/<B's package>/B.ecore" as B
    (This must be located before the generate statement!)
  4. Edit GenerateA.mwe2 file to add the reference to B's genmodel by inserting:
    referencedGenModels = "classpath:/<B's package>/B.genmodel" into ecore.EcoreGeneratorFragment fragment.
  5. Re-Generate A's Xtext project by running GenerateA.mwe2
And there it is ... now you can reference B's model elements within grammar A.

1 comment:

  1. Everything works fine, but I can use B's model elements only with "returns" statements like:

    MyParserRule returns B::OtherRule:
    bla, bla bla
    ;

    How can I write statements like

    grammar A with B ?

    ReplyDelete