Organization

The framework is highly modular and is organized in layers:

The Spirit is currently organized in basically two layers, the core and all the modules above the core: Debug, Attribute, Symbols, Tree, Utility and Error Handling. In the future, new layers may be built on top of existing layers. The framework's architecture is completely orthogonal. The relationship between the layers is totally acyclic. The core does not depend nor know the existence of the other layers. Modules in a layer do not depend on other modules in the same layer.

The client may use only the modules that she wants without incurring any compile time nor run time penalty. A minimalistic approach is to use only the core as is. The highly streamlined core is usable by itself. The core is highly suitable for tasks such as micro parsing.

The Debug module provides library wide parser debugging functionalities. This module essentially hooks itself up transparently into the core unintrusively and only when necessary.

Attribute module introduces advanced semantic action machinery with emphasis on extraction and passing of data up and down the parser hierarchy through inherited and synthesized attributes. Attributes may also be used to actually control the parsing. Parametric parsers are a form of dynamic parsers that change its behavior at run time based on some attribute or data.

Symbols module focuses on symbol table management. This module is rather basic as of now. The goal is to build a sub-framework that will be able to accommodate C++ style multiple scope mechanisms. C++ is a great model for the complexity of scoping that perhaps has no parallel in any other language. There are classes and inheritance, private, protected and public access restrictions, friends, namespaces, using declarations, using directives, Koenig lookup and more. The symbol table functionality we have now will be the basis of a complete facility that will attempt to model this.

I wish that I could ever see, a structure as lovely as a tree...

Parse Tree and Abstract Syntax Tree (AST) generation are handled by the Tree module. There are advantages with Parse Trees and Abstract Syntax Trees over semantic actions. You can make multiple passes over the data without having to re-parse the input. You can perform transformations on the tree. You can evaluate things in any order you want, whereas with attribute schemes you have to process in a begin to end fashion. You do not have to worry about backtracking and action side effects that may occur with an ambiguous grammar.

The Utility module is a set of commonly useful parsers that were found to be quite useful. This library of parsers significantly reduce the development time. There are parsers that handle common tasks such as list processing, comments, confix expressions, etc.

The framework would not be complete without Error Handling. C++'s exception handling mechanism is a perfect match for Spirit due to its highly recursive functional nature. C++ Exceptions are used extensively by this module for handling errors.

The Iterator module is independent of Spirit and may be used in other contexts as well. This module is a compilation of stand-alone iterators and iterator wrappers compatible with Spirit. Over the course of time, these iterators were found to be most useful for parsing with Spirit.