OcamlParser
For GSOC2016, Hugo implemented an experimental parser for the ASCEND modeling language that allows a faster rate of experimentation for new syntactic features compared to the existing ASCEND parser.
The new parser was designed to make it easy to parse ASCEND syntax into a syntax tree, perform transformation passes over this syntax tree and then serialize the result back into a textual format, which can be fed into the existing ASCEND compiler. This lets us implement new language features in terms of existing ones and experiment without needing to modify the core ASCEND compiler.
One advantage of having this new parser and syntax-tree tooling is that working with syntax trees is hard to do in the existing parsing architecture because ASCEND's C compiler parses and interprets the code at the same time, and doesn't give us a chance to apply syntax transformers before the code is interpreted. Another advantage of the new parser is that it is written in Ocaml, which as a functional programming language is specially suited for operating on tree-like data structures.
Compiling and Using the New Parser
The code for the new experimental parser as well as the infrastructure for writing syntax transformers can currently be found in the "hugo" branch of the ASCEND Subversion repository. It has not been merged into the trunk yet.
svn checkout http://svn.ascend4.org/branches/hugo ascend-hugo
To run the new parser and to write syntax transformers, you will need to install the Ocaml compiler, the Opam package manager and some additional dependencies.
# Install Ocaml and the Opam package manager sudo apt-install ocaml opam # Install Ocaml dependencies (locally) opam install menhir containers sequence
Then, go to the "ocaml" folder in the ASCEND source directory and build things with the makefile. Now you can start playing with the new parser.
cd ascend-hugo cd ocaml make
The makefile shows how to compile the code and the tests filder has some examples of how to run it. For more details see the README.txt in the ocaml folder.
Writing Syntax Transformers
The goal of this new Ocaml parser is to support syntax experiments that work by mapping ASCEND syntax trees (possibly with some extensions) into a vanilla ASCEND syntax tree that can be fed into the existing C compiler. However, writing these syntax tree transformers by hand can be a very laborious process because you need to write a lot of code just to traverse the syntax tree and get to the interesting leaves that we might want to modify. (Have a look at tokenize_tree to see how traversing a tree by hand looks like).
One of the ways to avoid boilerplate traversal code is to use the "Visitor Pattern" and write traversals by extending a default traversal that doesn't do anything. To support this pattern, there is an interface for syntax tree iterators in ast_iterator.ml as well as a default_iterator that doesn't do anything but that can be easily extended into an iterator that does something interesting in relevant nodes and just walks through everything else. There is also a similar system for transformers (functions that convert one AST into another) in ast_mapper.ml.
A good example of how to use the tree iteration and transformation modules can be found in infer_derivatives.ml. This syntax transformer receives makes DERIVATIVE OF declarations optional by inferring them from the uses of the der() operator throughout the program.