Jump to content

Spirit Parser Framework

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Bisqwit (talk | contribs) at 03:19, 18 February 2007 (Adding that one namespace prefix that 88.107.170.79 missed. But does it even compile now? The namespace is boost::spirit, not spirit. The "using" line also seems redundant now.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

The Spirit Parser Framework is an object oriented recursive descent parser generator framework implemented using template meta-programming techniques. Expression templates allow users to approximate the syntax of Extended Backus Naur Form (EBNF) completely in C++. Parser objects are composed through operator overloading and the result is a backtracking LL(inf) parser that is capable of parsing rather ambiguous grammars.

Spirit can be used for both lexing and parsing, together or separately.

This framework is part of the Boost libraries.

Operators

Because of limitations of the C++ language, the syntax of Spirit has been designed around the operator precedences of C++, while bearing resemblance to both EBNF and regular expressions.

syntax explanation
x >> y Match x followed by y.
*x Match x repeated zero or more times. (This is representing the Kleene star; C++ lacks a unary postfix operator *)
x | y Match x or y.
+x Match x repeated one or more times.
!x Match x zero or one time.
x & y Match x and y.
x - y Match x but not y.
x ^ y Match x or y but not both.
x [ function_expression ] Execute the function/functor returned by function_expression, if x matched.
( x ) Match x (can be used for priority grouping)
x % y Match one or more repetitions of x, separated by occurrences of y.
~x Match anything but x (only with character classes such as ch_p or alnum_p)

Example

#include <boost/spirit.hpp>
#include <boost/spirit/actor.hpp>
#include <string>
#include <iostream>

using boost::spirit;

int main(void)
{
    std::string input;
    
    std::cout << "Input a line.\n";
    std::getline(std::cin, input);
    
    std::cout << "Got '" << input << "'.\n";
    
    unsigned count = 0;
    
    spirit::parse(input.c_str(),
        *(  spirit::str_p("cat") [ spirit::increment_a(count) ]
          | spirit::anychar_p
         ));
    
    std::cout << "The input had " << count
              << " occurrences of 'cat'\n";
    return 0;
}