Of course, the best way to access the IR is to call the compiler directly from Haskell via the API. The IR is a tree data structure defined in Intclafer.hs. The abstract syntax is defined (automatically generated from the grammar) in Absclafer.hs. After parsing, which creates the abstract syntax tree (AST), the compiler desugars the AST into the IR. The IR is then used as the basis of subsequent analyses (e.g., name, inheritance, and type resolution, and scope analysis), and it is rewritten to contain the results of these analyses. Finally, a number of generators can be invoked to produce the various outputs, such as, Alloy code, HTML rendering, or Graph rendering in GraphViz DOT language.
The various generators are located in the Generator folder. Some generators are simple (like Html.hs), some produce output such that the traceability information is preserved (Alloy.hs). Some generators are driven by the abstract syntax, like the HTML one which needs to preserve the original model layout, some are driven by the IR, like the Alloy one, which is more concerned about the semantics than the syntax.
The second best way to access the IR is to use the JSON output. Running the compiler with
--mode=json model.cfrproduces a file
model.json. The JSON representation is an automatic serialization of the IR datatypes from Intclafer.hs and it contains full information about the model known to the compiler at the end of the compilation. This representation is used by the web tools 0.4.0.
--mode=choco model.cfrproduces a file
Finally, a parser can be generated directly using BNFC. We are using a customized BNFC to generate the Haskell implementation from Clafer grammar, but it can also be used to generate implementation for C, C++, C#, Java, and OCaml. This way is not recommended as it requires reimplementing all processing done by the compiler.