-
Notifications
You must be signed in to change notification settings - Fork 25
CGP Tutorial
This page proposes a five-step methodology for how to develop a code generator based on the Overture Code Generation Platform (CGP). The methodology was originally proposed in the paper "Extending the Overture code generator towards Isabelle syntax", which is available from the proceedings of the 13th Overture workshop
Below we describe the steps used to develop a new code generator.
The first step in the process is only necessary once. The remaining steps are done in an iterative manner. The approach is to start with a very small VDM example and go through the steps until the example is completely translated. Afterwards, the example should be expanded as little as possible and the steps repeated. This is done iteratively until the new CGP extension is complete.
Step 1 - Set up the CGP extension: Broadly speaking, the setting up of the CGP extension consists of subclassing the base code generator class – CodeGenBase
– that is the common extension point of the CGP. The base code generator is responsible for driving the code generation and providing access to the Intermediate Representation (IR) and various settings. It is also responsible for storing data used and generated throughout the code generation process.
Next, it is necessary to construct a new template manager for the extension. This can be done by subclassing the base TemplateManager
. This will provide access to the basic CGP TemplateStructure
class which manages an initial collection of template locations. If additional template locations are necessary, the template manager can be used to configure them. Finally, it is worth setting up a basic test infrastructure to drive the development process. This test infrastructure is responsible for processing a VDM source, passing the respective AST to the code generator and validating the translation outcome.
Step 2 - Add new nodes: If the target language construct being translated is sufficiently different from those of the base IR, then it is likely that a code generator needs extra nodes. If necessary, these can be provided by extending the IR as described in AST Extension. Once the extension is defined, the AstCreator tool must be invoked in order to generate the extension nodes.
Step 3 - Transform the IR: Constructs that are not supported by the code generator need to be transformed away, using either base IR nodes or extended nodes generated in the previous step. This is done by implementing one or more necessary transformations. It is recommended that transformations be as small as possible so that each transformation only changes the IR in terms of one concept such as removing comprehensions or reordering definitions.
The following code snippet shows how to apply transformations.
List<ExtIrClassDeclStatus> transformed = new Vector<>();
for (IRClassDeclStatus status : untransformed)
{
// Partial transformation applied directly
PartialTransformationFoo t1 = new PartialTransformationFoo();
generator.applyPartialTransformation(status, t1);
// Total transformations need wrapping
ExtIrClassDeclStatus eStatus = new ExtIrClassDeclStatus(status);
TotalTransformationBar t2 = new TotalTransformationBar();
generator.applyTotalTransformation(eStatus, t2);
transformed.add(eStatus);
}
Step 4 - Generate syntax: Once the IR is in a form suitable for code generation, syntax can be generated using the syntax generation framework of the CGP. This is done by creating the Apache Velocity template files for each of the nodes that is to be translated and updating the TemplateManager
accordingly.
Step 5 - Validate the translation: Validation of the translation should be done by means of the test infrastructure by comparing the translation output to a reference. This test should then be stored to use as regression in the continued development of the CGP extension. In Overture there is a Test Framework you should use to set up your test.