Hi all,
for some time, I’m working on ‘hollistic’ (i.e., concrete syntax definition, abstract syntax definition, well-formedness rules, code generators realizing semantics) language components and their composition in the context of the MontiCore language workbench. While this works well for the syntax definitions and well-formedness rules, the black-box composition of code generators is tricky and only works under some strong assumptions and requires manual adaptation between embedding and embedded generator.
Essentially, extension points of generators follow extension points (underspecified nonterminals) in the abstract syntax and expose the required interfaces (Assumption 1) of
- the generator they expect to call when meeting such an abstract syntax extension point and
- the main artifact (Assumption 2) produced by that generator.
These two assumptions entail that this works for target languages featuring the notion of interfaces only and that every generator produces a dedicated main artifact - which is doable but clumsy when, e.g., embedding a code generator for guard expressions into another one for statecharts.
As each generator exposes these two artifacts, they can be adapted (manually, unfortunately) and enable black-box generator composition.
Do you have experience with composing/embedding/integration independently developed code generators? How did that work for you? Which assumptions did you have to make?
Looking forward to discussing with you.
Best,
Andreas
(Figure from Modeling Language Variability with Reusable Language Components)
@ Admins If this does not fit into ‘compliers’ please update as considered suitable