Child pages
  • Generator User Guide Demo5
Skip to end of metadata
Go to start of metadata

Generator User Guide Demo 5

In this demo we will learn how to use generation scripts and utility classes.

There are two kinds of generation scripts: pre-processing and post-processing scripts.
Pre-processing scripts are invoked before applying of generator rules and usually alter input model in a way that makes it easier for further processing by rules.
Post-processing scripts are invoked after all generator rules are done and are applied to output model.

New Language

  • create new language 'generator_demo.L5'
  • in language properties dialog add extended language : 'jetbrains.mps.sampleXML'
  • create new generator for this language (see Demo 1 for details)
  • delete (empty) mapping configuration 'main' from L5 generator
  • copy-paste all nodes from L4 generator to L5 generator

when pasting nodes - don't forget to exclude L4 generator model from imports

Icon

See Demo 2 for details.

copy-paste all nodes in one step

Icon

Doing so you won't be even offered to import generator model from L4.

New Test Model

  • in solution 'test_models' clone model 'test4' to model 'test5'
  • in model properties dialog replace 'engaged on generation' language L4 -> L5 (see Demo 2 for details)
  • in model 'test5' open document 'Panel'
  • add a Text node to the 'panel' element:

Pre-processing Script

Our L5 generator doesn't support text nodes, but text node in this context has the same meaning as 'label' element with 'text' attribute.
Therefore, instead of adding more rules to our generator, we will add pre-processing script which will convert text nodes to 'label' elements and let existing rules do rest of the job.

  • in model 'main@generator' (in L5 generator) create root node mapping script
  • give it name 'fix_text'
  • set script kind = pre-process input model
  • set modifies model = true.
  • enter code which will perform search and replace of all text nodes in model:

  • add the 'fix_text' script to mapping configuration 'main' to the pre-processing scripts section:

First Test

Re-generate generator, generate files from model 'test5', run the generated 'generator_demo.test5.DemoApp' class.

Utility Classes in Generator

Now suppose we got an idea to fix possible syntax and stylistic errors in generated texts. We can create a post-processing script to do that but those NLP algorithms tend to be quite complex, so we decide to develop them in a separate utility class.

The problem is that an utility class can not be created in generator model 'main@generator' because any root node in any model with stereotype 'generator' is treated as a root template.
The solution is to create another model in generator module:

  • select generator node (L5 generator) in tree and choose New->Model in popup menu:

  • give the new model name: 'util':

  • in model 'util' create class 'TextUtil'
  • add static method 'fixText()' to class 'TextUtil':

We are going to call the 'fixText()' method in post-processing script and pass output model as a parameter. The output model contains classes, methods, expressions and so on. Thus we are manipulating with a java-like syntax tree here.
The 'fixText()' method will replace all strings "MPS" with strings "JetBrains MPS".

Post-processing Script

Now we can use this utility method 'fixText()' in post-processing script:

  • in model 'main@generator' (in L5 generator) create new mapping script
  • give it name 'refine_text'
  • import model 'generator_demo.L5.generator.template.util' to model 'main@generator' (see Demo 1 for details on model importing)

    importing root

    Icon

    You can also use Ctrl+R command and type 'TextUtil' to import the 'generator_demo.L5.generator.template.util' model

  • in mapping script 'refine_text' enter code as shown:

  • add the 'refine_text' script to post-processing scripts section in mapping configuration 'main':

Re-generate generator.
You can use Ctrl-F9 (generate all changed models in module). (warning) Note that Shift-F9 (generate current model) is not enough any more because now we have two models requiring generation.

Second Test

Generate model 'test5', run 'DemoApp'.

End of Demo 5

  • No labels