Functor Parser

The simplest way to write your hand coded parser that works well with the rest of the Spirit library is to simply write a functor parser.

A functor parser is expected to have the interface:

    struct functor
    {
        typedef T result_t;

        template <typename ScannerT>
        std::ptrdiff_t
        operator()(ScannerT const& scan, result_t& result) const;
    };

where typedef T result_t; is the attribute type of the parser that will be passed back to the match result (see In-depth: The Parser). If the parser does not need to return an attribute, this can simply be nil_t. The std::ptrdiff_t result is the number of matching characters matched by your parser. A negative value flags an unsuccessful match.

A conforming functor parser can transformed into a well formed Spirit parser by wrapping it in the functor_parser template:

    functor_parser<functor> functor_p;

Example

The following example puts the functor_parser into action:

    struct number_parser
    {
        typedef int result_t;
        template <typename ScannerT>
        std::ptrdiff_t
        operator()(ScannerT const& scan, result_t& result) const
        {
            if (scan.at_end())
                return -1;

            char ch = *scan;
            if (ch < '0' || ch > '9')
                return -1;

            result = 0;
            std::ptrdiff_t len = 0;

            do
            {
                result = result*10 + int(ch - '0');
                ++len;
                ++scan;
            } while (!scan.at_end() && (ch = *scan, ch >= '0' && ch <= '9'));

            return len;
        }
    };

    functor_parser<number_parser> number_parser_p;

The full source code can be viewed here. This is part of the Spirit distribution.

To further understand the implementation, see In-depth: The Scanner for the scanner API details. We now have a parser number_parser_p that we can use just like any other Spirit parser. Example:

    r = number_parser_p >> *(',' >> number_parser_p);