Chapter 52. Transformer Generation

Generate code by writing a transformer that navigates the input model and produces output.

image

52.1 How It Works

Transformer Generation involves writing a program that takes the Semantic Model as input and produces an output in the form of source code for the target environment. I like to think of transformers in terms of input-driven and output-driven sections. Output-driven transformation starts from the required output and dives into the input to gather the data it needs as it goes. Input-driven transformation walks the input data structure and produces output.

For an example, consider generating a web page based on a catalog of products. An output-driven approach would start with the structure of the web page, perhaps with a routine like this:

renderHeader();
renderBody();
renderFooter();

An input driven transformation looks instead at the input data structure and navigates through that, perhaps like this:

image

Often, transformers use a combination of the two approaches. I seem to regularly run into situations where the outer logic is output-driven, but it calls routines that are more input-driven. The outer logic describes the broad structure of the output document, dividing it into logical sections, while the inner section produces output driven by a particular kind of input data. In any case, I find it useful to think of each routine in the transformation as either input-driven or output-driven and to be conscious of which I’m using.

Many transformations can go directly from Semantic Model to target source, but for more complicated transforms it can be useful to break down the transformation into multiple steps. A two-step transform, for instance, would walk the input model and produce an output model. This output model would be a model, rather than a text, but more oriented towards the generated output. A second step might then walk the output model and produce the output text. Using a multistep transform is useful when the transform is complicated, or if you have multiple output texts to produce from the same input that share some characteristics. With multiple output texts, you can produce, in the first-stage transform, a single output model with the common elements. The difference between the output texts can then be placed in varying second stages.

With a multistage approach, you can also mix techniques, for example using Transformer Generation for the first stage and Templated Generation for the second stage.

52.2 When to Use It

A single-stage Transformer Generation is a good choice when the output text has a simple relationship with the input model and most of the output text is generated. In this case, Transformer Generation is very easy to write and doesn’t require introducing a templating tool.

Transformer Generation with multiple stages can be very useful when the relationship between input and output is more complex, as each stage can handle a different aspect of the problem.

If you use Model-Aware Generation, you can usually populate the model with a simple sequence of calls, which is easy to generate with Transformer Generation.

52.3 Secret Panel Controller (Java generating C)

Using Model-Aware Generation often goes with Transformer Generation as the separation between generated code and static code is clear, allowing any sections of generated code to have very little static code. So in this case, I’ll generate the code for the secret panel controller from the example in Model-Aware Generation. To save you flipping pages, here is the code I need to generate:

image

image

The output that I need to generate has a very simple structure, evident from the way I construct the outer routine of the generator.

image

This code is a typical output-driven outer routine of a transformer. I might as well go through each of these steps in the order they come in. The header just writes out the static stuff I need at the top of the file.

image

When I create the generator, I create it with the state machine that it will work on.

image

The first time I use this is to generate the event declarations.

image

The commands and state declarations are similarly easy.

image

Next, I generate the body (actions and transitions) for each state. In this case, I have to declare all the states before I can declare transitions since I’ll get an error if I forward-reference a state.

image

This also demonstrates a flip into an input-driven style. The code that’s generated in each case follows the structure of the input model. This is fine, as it doesn’t matter in which order I declare actions and transitions. This code also shows generating a comment with dynamic data.

Finally, I generate the reset events.

image

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.62.94