Support builder composition in Spoofax API
Builder composition is quite common and typically happens in Stratego code, where a builder invokes another builder first, before it performs its own operation. For more advanced compositions which involve builders from different languages, this leads to unnecessary source code dependencies. Here are two examples:
- To generate Java class files from a MiniJava program, the first builder generates Jasmin code, while the second builder turns Jasmin code into Java class files. The second builder should be completely reused from the Jasmin language, without introducing any source code dependencies.
- To generate Java code from a GreenMarl program, the GM compiler first generates a Java AST, which then needs to be pretty-printed. The pretty-printer could be a reusable builder from Javafront.
The current API suggests three basic language processing steps: parsing, analysing, and transformation. Thereby, analysis can only be applied on a parse result. This prevents builder composition, since analysis should be applicable to transformation results as well, which would allow us to chain several analysis-transformation-pairs. The API is too restrictive here, to support analysis only on parse results. Conceptually, parse results and transformation results should share an interface which captures an analysis input. I would prefer this over a fix, which would allow the construction of parse results from transformation results.
Workaround (by Gabriƫl)
Feeding the AST into the analyzer requires creating an
ISpoofaxParseUnit
, which is a bit tedious currently.Submitted by Guido Wachsmuth on 28 June 2016 at 12:36
- Create an
ISpoofaxInputUnit
with theISpoofaxUnitService
. The input unit requires the text that is normally passed to the parser, but you can use an empty string there because you are not going to parse.- Create a
ISpoofaxParseUnit
with that input unit, then pass that into the analyser. The parse unit requires the input unit and aParseContrib
, which you can just create withnew ParseContrib(true, true, ast, Iterables2.<IMessage>empty(), -1)
.- Pass the parse unit into the analyser.
Log in to post comments