code:
/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    http://spirit.sourceforge.net/

  Distributed under the Boost Software License, Version 1.0. (See accompanying
  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_PARSER_HPP)
#define BOOST_SPIRIT_PARSER_HPP

#include <boost/config.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/scanner/scanner.hpp>
#include <boost/spirit/home/classic/core/nil.hpp>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    template <typename ParserT, typename ActionT>
    class action; //  forward declaration

    ///////////////////////////////////////////////////////////////////////////
    //
    //  Parser categories
    //
    //      Helper template classes to distinguish different types of
    //      parsers. The following categories are the most generic. More
    //      specific types may inherit from these. Each parser has a typedef
    //      parser_category_t that defines its category. By default, if one
    //      is not specified, it will inherit from the base parser class
    //      which typedefs its parser_category_t as plain_parser_category.
    //
    //          - plain parser has nothing special
    //          - binary parser has subject a and b (e.g. alternative)
    //          - unary parser has single subject  (e.g. kleene star)
    //          - action parser has an attached action parser
    //
    ///////////////////////////////////////////////////////////////////////////
    struct plain_parser_category {};
    struct binary_parser_category       : plain_parser_category {};
    struct unary_parser_category        : plain_parser_category {};
    struct action_parser_category       : unary_parser_category {};

    ///////////////////////////////////////////////////////////////////////////
    //
    //  parser_result metafunction
    //
    //      Given a scanner type ScannerT and a parser type ParserT, the
    //      parser_result metafunction provides the actual result of the
    //      parser.
    //
    //  Usage:
    //
    //      typename parser_result<ParserT, ScannerT>::type
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename ParserT, typename ScannerT>
    struct parser_result
    {
        typedef typename boost::remove_reference<ParserT>::type parser_type;
        typedef typename parser_type::template result<ScannerT>::type type;
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  parser class
    //
    //      This class is a protocol base class for all parsers. This is
    //      essentially an interface contract. The parser class does not
    //      really know how to parse anything but instead relies on the
    //      template parameter DerivedT (which obviously is assumed to be a
    //      subclass) to do the actual parsing.
    //
    //      Concrete sub-classes inheriting from parser must have a
    //      corresponding member function parse(...) compatible with the
    //      conceptual Interface:
    //
    //          template <typename ScannerT>
    //          RT parse(ScannerT const& scan) const;
    //
    //      where RT is the desired return type of the parser and ScannerT
    //      scan is the scanner (see scanner.hpp).
    //
    //      Concrete sub-classes inheriting from parser in most cases need to
    //      have a nested meta-function result that returns the result type
    //      of the parser's parse member function, given a scanner type. The
    //      meta-function has the form:
    //
    //          template <typename ScannerT>
    //          struct result
    //          {
    //              typedef RT type;
    //          };
    //
    //      where RT is the desired return type of the parser. This is
    //      usually, but not always, dependent on the template parameter
    //      ScannerT. If a parser does not supply a result metafunction, a
    //      default is provided by the base parser class.
    //
    //      The parser's derived() member function returns a reference to the
    //      parser as its derived object.
    //
    //      An operator[] is provided. The operator returns a semantic action
    //      handler (see actions.hpp).
    //
    //      Each parser has a typedef embed_t. This typedef specifies how a
    //      parser is embedded in a composite (see composite.hpp). By
    //      default, if one is not specified, the parser will be embedded by
    //      value. That is, a copy of the parser is placed as a member
    //      variable of the composite. Most parsers are embedded by value. In
    //      certain situations however, this is not desirable or possible.
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename DerivedT>
    struct parser
    {
        typedef DerivedT                embed_t;
        typedef DerivedT                derived_t;
        typedef plain_parser_category   parser_category_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename match_result<ScannerT, nil_t>::type type;
        };

        DerivedT& derived()
        {
            return *static_cast<DerivedT*>(this);
        }

        DerivedT const& derived() const
        {
            return *static_cast<DerivedT const*>(this);
        }

        template <typename ActionT>
        action<DerivedT, ActionT>
        operator[](ActionT const& actor) const
        {
            return action<DerivedT, ActionT>(derived(), actor);
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  parse_info
    //
    //      Results returned by the free parse functions:
    //
    //      stop:   points to the final parse position (i.e parsing
    //              processed the input up to this point).
    //
    //      hit:    true if parsing is successful. This may be full:
    //              the parser consumed all the input, or partial:
    //              the parser consumed only a portion of the input.
    //
    //      full:   true when we have a full hit (i.e the parser
    //              consumed all the input.
    //
    //      length: The number of characters consumed by the parser.
    //              This is valid only if we have a successful hit
    //              (either partial or full).
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename IteratorT = char const*>
    struct parse_info
    {
        IteratorT   stop;
        bool        hit;
        bool        full;
        std::size_t length;

        parse_info(
            IteratorT const& stop_ = IteratorT(),
            bool hit_ = false,
            bool full_ = false,
            std::size_t length_ = 0)
        : stop(stop_)
        , hit(hit_)
        , full(full_)
        , length(length_) {}

        template <typename ParseInfoT>
        parse_info(ParseInfoT const& pi)
        : stop(pi.stop)
        , hit(pi.hit)
        , full(pi.full)
        , length(pi.length) {}
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  Generic parse function
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename IteratorT, typename DerivedT>
    parse_info<IteratorT>
    parse(
        IteratorT const&        first,
        IteratorT const&        last,
        parser<DerivedT> const& p);

    ///////////////////////////////////////////////////////////////////////////
    //
    //  Parse function for null terminated strings
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename CharT, typename DerivedT>
    parse_info<CharT const*>
    parse(
        CharT const*            str,
        parser<DerivedT> const& p);

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace BOOST_SPIRIT_CLASSIC_NS

#endif

#include <boost/spirit/home/classic/core/impl/parser.ipp>


code:
/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    Copyright (c) 2001-2003 Hartmut Kaiser
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_NUMERICS_IPP
#define BOOST_SPIRIT_NUMERICS_IPP

#include <boost/config/no_tr1/cmath.hpp>
#include <limits>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    struct sign_parser; // forward declaration only

    namespace impl
    {
        ///////////////////////////////////////////////////////////////////////
        //
        //  Extract the prefix sign (- or +)
        //
        ///////////////////////////////////////////////////////////////////////
        template <typename ScannerT>
        bool
        extract_sign(ScannerT const& scan, std::size_t& count)
        {
            //  Extract the sign
            count = 0;
            bool neg = *scan == '-';
            if (neg || (*scan == '+'))
            {
                ++scan;
                ++count;
                return neg;
            }

            return false;
        }

        ///////////////////////////////////////////////////////////////////////
        //
        //  Traits class for radix specific number conversion
        //
        //      Convert a digit from character representation, ch, to binary
        //      representation, returned in val.
        //      Returns whether the conversion was successful.
        //
        //        template<typename CharT> static bool digit(CharT ch, T& val);
        //
        ///////////////////////////////////////////////////////////////////////
        template<const int Radix>
        struct radix_traits;

        ////////////////////////////////// Binary
        template<>
        struct radix_traits<2>
        {
            template<typename CharT, typename T>
            static bool digit(CharT ch, T& val)
            {
                val = ch - '0';
                return ('0' == ch || '1' == ch);
            }
        };

        ////////////////////////////////// Octal
        template<>
        struct radix_traits<8>
        {
            template<typename CharT, typename T>
            static bool digit(CharT ch, T& val)
            {
                val = ch - '0';
                return ('0' <= ch && ch <= '7');
            }
        };

        ////////////////////////////////// Decimal
        template<>
        struct radix_traits<10>
        {
            template<typename CharT, typename T>
            static bool digit(CharT ch, T& val)
            {
                val = ch - '0';
                return impl::isdigit_(ch);
            }
        };

        ////////////////////////////////// Hexadecimal
        template<>
        struct radix_traits<16>
        {
            template<typename CharT, typename T>
            static bool digit(CharT ch, T& val)
            {
                if (radix_traits<10>::digit(ch, val))
                    return true;

                CharT lc = impl::tolower_(ch);
                if ('a' <= lc && lc <= 'f')
                {
                    val = lc - 'a' + 10;
                    return true;
                }
                return false;
            }
        };

        ///////////////////////////////////////////////////////////////////////
        //
        //      Helper templates for encapsulation of radix specific
        //      conversion of an input string to an integral value.
        //
        //      main entry point:
        //
        //          extract_int<Radix, MinDigits, MaxDigits, Accumulate>
        //              ::f(first, last, n, count);
        //
        //          The template parameter Radix represents the radix of the
        //          number contained in the parsed string. The template
        //          parameter MinDigits specifies the minimum digits to
        //          accept. The template parameter MaxDigits specifies the
        //          maximum digits to parse. A -1 value for MaxDigits will
        //          make it parse an arbitrarilly large number as long as the
        //          numeric type can hold it. Accumulate is either
        //          positive_accumulate<Radix> (default) for parsing positive
        //          numbers or negative_accumulate<Radix> otherwise.
        //          Checking is only performed when std::numeric_limits<T>::
        //          is_specialized is true. Otherwise, there's no way to
        //          do the check.
        //
        //          scan.first and scan.last are iterators as usual (i.e.
        //          first is mutable and is moved forward when a match is
        //          found), n is a variable that holds the number (passed by
        //          reference). The number of parsed characters is added to
        //          count (also passed by reference)
        //
        //      NOTE:
        //              Returns a non-match, if the number to parse
        //              overflows (or underflows) the used type.
        //
        //      BEWARE:
        //              the parameters 'n' and 'count' should be properly
        //              initialized before calling this function.
        //
        ///////////////////////////////////////////////////////////////////////
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4127) //conditional expression is constant
#endif

        template <typename T, int Radix>
        struct positive_accumulate
        {
            //  Use this accumulator if number is positive
            static bool add(T& n, T digit)
            {
                if (std::numeric_limits<T>::is_specialized)
                {
                    static T const max = (std::numeric_limits<T>::max)();
                    static T const max_div_radix = max/Radix;

                    if (n > max_div_radix)
                        return false;
                    n *= Radix;

                    if (n > max - digit)
                        return false;
                    n += digit;

                    return true;
                }
                else
                {
                    n *= Radix;
                    n += digit;
                    return true;
                }
            }
        };

        template <typename T, int Radix>
        struct negative_accumulate
        {
            //  Use this accumulator if number is negative
            static bool add(T& n, T digit)
            {
                if (std::numeric_limits<T>::is_specialized)
                {
                    typedef std::numeric_limits<T> num_limits;
                    static T const min =
                        (!num_limits::is_integer && num_limits::is_signed && num_limits::has_denorm) ?
                        -(num_limits::max)() : (num_limits::min)();
                    static T const min_div_radix = min/Radix;

                    if (n < min_div_radix)
                        return false;
                    n *= Radix;

                    if (n < min + digit)
                        return false;
                    n -= digit;

                    return true;
                }
                else
                {
                    n *= Radix;
                    n -= digit;
                    return true;
                }
            }
        };

        template <int MaxDigits>
        inline bool allow_more_digits(std::size_t i)
        {
            return i < MaxDigits;
        }

        template <>
        inline bool allow_more_digits<-1>(std::size_t)
        {
            return true;
        }

        //////////////////////////////////
        template <
            int Radix, unsigned MinDigits, int MaxDigits,
            typename Accumulate
        >
        struct extract_int
        {
            template <typename ScannerT, typename T>
            static bool
            f(ScannerT& scan, T& n, std::size_t& count)
            {
                std::size_t i = 0;
                T digit;
                while( allow_more_digits<MaxDigits>(i) && !scan.at_end() &&
                    radix_traits<Radix>::digit(*scan, digit) )
                {
                    if (!Accumulate::add(n, digit))
                        return false; // Overflow
                    ++i, ++scan, ++count;
                }
                return i >= MinDigits;
            }
        };

        ///////////////////////////////////////////////////////////////////////
        //
        //  uint_parser_impl class
        //
        ///////////////////////////////////////////////////////////////////////
        template <
            typename T = unsigned,
            int Radix = 10,
            unsigned MinDigits = 1,
            int MaxDigits = -1
        >
        struct uint_parser_impl
            : parser<uint_parser_impl<T, Radix, MinDigits, MaxDigits> >
        {
            typedef uint_parser_impl<T, Radix, MinDigits, MaxDigits> self_t;

            template <typename ScannerT>
            struct result
            {
                typedef typename match_result<ScannerT, T>::type type;
            };

            template <typename ScannerT>
            typename parser_result<self_t, ScannerT>::type
            parse(ScannerT const& scan) const
            {
                if (!scan.at_end())
                {
                    T n = 0;
                    std::size_t count = 0;
                    typename ScannerT::iterator_t save = scan.first;
                    if (extract_int<Radix, MinDigits, MaxDigits,
                        positive_accumulate<T, Radix> >::f(scan, n, count))
                    {
                        return scan.create_match(count, n, save, scan.first);
                    }
                    // return no-match if number overflows
                }
                return scan.no_match();
            }
        };

        ///////////////////////////////////////////////////////////////////////
        //
        //  int_parser_impl class
        //
        ///////////////////////////////////////////////////////////////////////
        template <
            typename T = unsigned,
            int Radix = 10,
            unsigned MinDigits = 1,
            int MaxDigits = -1
        >
        struct int_parser_impl
            : parser<int_parser_impl<T, Radix, MinDigits, MaxDigits> >
        {
            typedef int_parser_impl<T, Radix, MinDigits, MaxDigits> self_t;

            template <typename ScannerT>
            struct result
            {
                typedef typename match_result<ScannerT, T>::type type;
            };

            template <typename ScannerT>
            typename parser_result<self_t, ScannerT>::type
            parse(ScannerT const& scan) const
            {
                typedef extract_int<Radix, MinDigits, MaxDigits,
                    negative_accumulate<T, Radix> > extract_int_neg_t;
                typedef extract_int<Radix, MinDigits, MaxDigits,
                    positive_accumulate<T, Radix> > extract_int_pos_t;

                if (!scan.at_end())
                {
                    T n = 0;
                    std::size_t count = 0;
                    typename ScannerT::iterator_t save = scan.first;

                    bool hit = impl::extract_sign(scan, count);

                    if (hit)
                        hit = extract_int_neg_t::f(scan, n, count);
                    else
                        hit = extract_int_pos_t::f(scan, n, count);

                    if (hit)
                        return scan.create_match(count, n, save, scan.first);
                    else
                        scan.first = save;
                    // return no-match if number overflows or underflows
                }
                return scan.no_match();
            }
        };

        ///////////////////////////////////////////////////////////////////////
        //
        //  real_parser_impl class
        //
        ///////////////////////////////////////////////////////////////////////
        template <typename RT, typename T, typename RealPoliciesT>
        struct real_parser_impl
        {
            typedef real_parser_impl<RT, T, RealPoliciesT> self_t;

            template <typename ScannerT>
            RT parse_main(ScannerT const& scan) const
            {
                if (scan.at_end())
                    return scan.no_match();
                typename ScannerT::iterator_t save = scan.first;

                typedef typename parser_result<sign_parser, ScannerT>::type
                    sign_match_t;
                typedef typename parser_result<chlit<>, ScannerT>::type
                    exp_match_t;

                sign_match_t    sign_match = RealPoliciesT::parse_sign(scan);
                std::size_t     count = sign_match ? sign_match.length() : 0;
                bool            neg = sign_match.has_valid_attribute() ?
                                    sign_match.value() : false;

                RT              n_match = RealPoliciesT::parse_n(scan);
                T               n = n_match.has_valid_attribute() ?
                                    n_match.value() : T(0);
                bool            got_a_number = n_match;
                exp_match_t     e_hit;

                if (!got_a_number && !RealPoliciesT::allow_leading_dot)
                     return scan.no_match();
                else
                    count += n_match.length();

                if (neg)
                    n = -n;

                if (RealPoliciesT::parse_dot(scan))
                {
                    //  We got the decimal point. Now we will try to parse
                    //  the fraction if it is there. If not, it defaults
                    //  to zero (0) only if we already got a number.

                    if (RT hit = RealPoliciesT::parse_frac_n(scan))
                    {
#if !defined(BOOST_NO_STDC_NAMESPACE)
                        using namespace std;  // allow for ADL to find pow()
#endif
                        hit.value(hit.value()
                            * pow(T(10), T(-hit.length())));
                        if (neg)
                            n -= hit.value();
                        else
                            n += hit.value();
                        count += hit.length() + 1;

                    }

                    else if (!got_a_number ||
                        !RealPoliciesT::allow_trailing_dot)
                        return scan.no_match();

                    e_hit = RealPoliciesT::parse_exp(scan);
                }
                else
                {
                    //  We have reached a point where we
                    //  still haven't seen a number at all.
                    //  We return early with a no-match.
                    if (!got_a_number)
                        return scan.no_match();

                    //  If we must expect a dot and we didn't see
                    //  an exponent, return early with a no-match.
                    e_hit = RealPoliciesT::parse_exp(scan);
                    if (RealPoliciesT::expect_dot && !e_hit)
                        return scan.no_match();
                }

                if (e_hit)
                {
                    //  We got the exponent prefix. Now we will try to parse the
                    //  actual exponent. It is an error if it is not there.
                    if (RT e_n_hit = RealPoliciesT::parse_exp_n(scan))
                    {
#if !defined(BOOST_NO_STDC_NAMESPACE)
                        using namespace std;    // allow for ADL to find pow()
#endif
                        n *= pow(T(10), T(e_n_hit.value()));
                        count += e_n_hit.length() + e_hit.length();
                    }
                    else
                    {
                        //  Oops, no exponent, return a no-match
                        return scan.no_match();
                    }
                }

                return scan.create_match(count, n, save, scan.first);
            }

            template <typename ScannerT>
            static RT parse(ScannerT const& scan)
            {
                static self_t this_;
                return impl::implicit_lexeme_parse<RT>(this_, scan, scan);
            }
        };

#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif

    }   //  namespace impl

///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace boost::spirit

#endif

license: mit


code:
/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    Copyright (c) 2003 Martin Wille
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_PRIMITIVES_IPP)
#define BOOST_SPIRIT_PRIMITIVES_IPP

#include <cctype>
#if !defined(BOOST_NO_CWCTYPE)
#include <cwctype>
#endif

#include <string> // char_traits

#if defined(BOOST_MSVC)
#  pragma warning (push)
#  pragma warning(disable:4800)
#endif

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    template <typename DrivedT> struct char_parser;

    namespace impl
    {
        template <typename IteratorT>
        inline IteratorT
        get_last(IteratorT first)
        {
            while (*first)
                first++;
            return first;
        }

        template<
            typename RT,
            typename IteratorT,
            typename ScannerT>
        inline RT
        string_parser_parse(
            IteratorT str_first,
            IteratorT str_last,
            ScannerT& scan)
        {
            typedef typename ScannerT::iterator_t iterator_t;
            iterator_t saved = scan.first;
            std::size_t slen = str_last - str_first;

            while (str_first != str_last)
            {
                if (scan.at_end() || (*str_first != *scan))
                    return scan.no_match();
                ++str_first;
                ++scan;
            }

            return scan.create_match(slen, nil_t(), saved, scan.first);
        }

    ///////////////////////////////////////////////////////////////////////////
    //
    // Conversion from char_type to int_type
    //
    ///////////////////////////////////////////////////////////////////////////

        //  Use char_traits for char and wchar_t only, as these are the only
        //  specializations provided in the standard. Other types are on their
        //  own.
        //
        //  For UDT, one may override:
        //
        //      isalnum
        //      isalpha
        //      iscntrl
        //      isdigit
        //      isgraph
        //      islower
        //      isprint
        //      ispunct
        //      isspace
        //      isupper
        //      isxdigit
        //      isblank
        //      isupper
        //      tolower
        //      toupper
        //
        //  in a namespace suitable for Argument Dependent lookup or in
        //  namespace std (disallowed by the standard).

        template <typename CharT>
        struct char_type_char_traits_helper
        {
            typedef CharT char_type;
            typedef typename std::char_traits<CharT>::int_type int_type;

            static int_type to_int_type(CharT c)
            {
                return std::char_traits<CharT>::to_int_type(c);
            }

            static char_type to_char_type(int_type i)
            {
                return std::char_traits<CharT>::to_char_type(i);
            }
        };

        template <typename CharT>
        struct char_traits_helper
        {
            typedef CharT char_type;
            typedef CharT int_type;

            static CharT & to_int_type(CharT & c)
            {
                return c;
            }

            static CharT & to_char_type(CharT & c)
            {
                return c;
            }
        };

        template <>
        struct char_traits_helper<char>
            : char_type_char_traits_helper<char>
        {
        };

#if !defined(BOOST_NO_CWCTYPE)

        template <>
        struct char_traits_helper<wchar_t>
            : char_type_char_traits_helper<wchar_t>
        {
        };

#endif

        template <typename CharT>
        inline typename char_traits_helper<CharT>::int_type
        to_int_type(CharT c)
        {
            return char_traits_helper<CharT>::to_int_type(c);
        }

        template <typename CharT>
        inline CharT
        to_char_type(typename char_traits_helper<CharT>::int_type c)
        {
            return char_traits_helper<CharT>::to_char_type(c);
        }

        ///////////////////////////////////////////////////////////////////////
        //
        //  Convenience functions
        //
        ///////////////////////////////////////////////////////////////////////

        template <typename CharT>
        inline bool
        isalnum_(CharT c)
        {
            using namespace std;
            return isalnum(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        isalpha_(CharT c)
        {
            using namespace std;
            return isalpha(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        iscntrl_(CharT c)
        {
            using namespace std;
            return iscntrl(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        isdigit_(CharT c)
        {
            using namespace std;
            return isdigit(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        isgraph_(CharT c)
        {
            using namespace std;
            return isgraph(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        islower_(CharT c)
        {
            using namespace std;
            return islower(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        isprint_(CharT c)
        {
            using namespace std;
            return isprint(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        ispunct_(CharT c)
        {
            using namespace std;
            return ispunct(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        isspace_(CharT c)
        {
            using namespace std;
            return isspace(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        isupper_(CharT c)
        {
            using namespace std;
            return isupper(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        isxdigit_(CharT c)
        {
            using namespace std;
            return isxdigit(to_int_type(c)) ? true : false;
        }

        template <typename CharT>
        inline bool
        isblank_(CharT c)
        {
            return (c == ' ' || c == '\t');
        }

        template <typename CharT>
        inline CharT
        tolower_(CharT c)
        {
            using namespace std;
            return to_char_type<CharT>(tolower(to_int_type(c)));
        }

        template <typename CharT>
        inline CharT
        toupper_(CharT c)
        {
            using namespace std;
            return to_char_type<CharT>(toupper(to_int_type(c)));
        }

#if !defined(BOOST_NO_CWCTYPE)

        inline bool
        isalnum_(wchar_t c)
        {
            using namespace std;
            return iswalnum(to_int_type(c)) ? true : false;
        }

        inline bool
        isalpha_(wchar_t c)
        {
            using namespace std;
            return iswalpha(to_int_type(c)) ? true : false;
        }

        inline bool
        iscntrl_(wchar_t c)
        {
            using namespace std;
            return iswcntrl(to_int_type(c)) ? true : false;
        }

        inline bool
        isdigit_(wchar_t c)
        {
            using namespace std;
            return iswdigit(to_int_type(c)) ? true : false;
        }

        inline bool
        isgraph_(wchar_t c)
        {
            using namespace std;
            return iswgraph(to_int_type(c)) ? true : false;
        }

        inline bool
        islower_(wchar_t c)
        {
            using namespace std;
            return iswlower(to_int_type(c)) ? true : false;
        }

        inline bool
        isprint_(wchar_t c)
        {
            using namespace std;
            return iswprint(to_int_type(c)) ? true : false;
        }

        inline bool
        ispunct_(wchar_t c)
        {
            using namespace std;
            return iswpunct(to_int_type(c)) ? true : false;
        }

        inline bool
        isspace_(wchar_t c)
        {
            using namespace std;
            return iswspace(to_int_type(c)) ? true : false;
        }

        inline bool
        isupper_(wchar_t c)
        {
            using namespace std;
            return iswupper(to_int_type(c)) ? true : false;
        }

        inline bool
        isxdigit_(wchar_t c)
        {
            using namespace std;
            return iswxdigit(to_int_type(c)) ? true : false;
        }

        inline bool
        isblank_(wchar_t c)
        {
            return (c == L' ' || c == L'\t');
        }

        inline wchar_t
        tolower_(wchar_t c)
        {
            using namespace std;
            return to_char_type<wchar_t>(towlower(to_int_type(c)));
        }

        inline wchar_t
        toupper_(wchar_t c)
        {
            using namespace std;
            return to_char_type<wchar_t>(towupper(to_int_type(c)));
        }

#endif // !defined(BOOST_NO_CWCTYPE)

}

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace boost::spirit::impl

#ifdef BOOST_MSVC
#pragma warning (pop)
#endif

#endif


code:
/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    Copyright (c) 2001-2003 Hartmut Kaiser
    http://spirit.sourceforge.net/

  Distributed under the Boost Software License, Version 1.0. (See accompanying
  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_NUMERICS_HPP
#define BOOST_SPIRIT_NUMERICS_HPP

#include <boost/config.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/directives.hpp>

#include <boost/spirit/home/classic/core/primitives/numerics_fwd.hpp>
#include <boost/spirit/home/classic/core/primitives/impl/numerics.ipp>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    ///////////////////////////////////////////////////////////////////////////
    //
    //  uint_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <
        typename T,
        int Radix,
        unsigned MinDigits,
        int MaxDigits
    >
    struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits> >
    {
        typedef uint_parser<T, Radix, MinDigits, MaxDigits> self_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename match_result<ScannerT, T>::type type;
        };

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef impl::uint_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
            typedef typename parser_result<impl_t, ScannerT>::type result_t;
            return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  int_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <
        typename T,
        int Radix,
        unsigned MinDigits,
        int MaxDigits
    >
    struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits> >
    {
        typedef int_parser<T, Radix, MinDigits, MaxDigits> self_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename match_result<ScannerT, T>::type type;
        };

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef impl::int_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
            typedef typename parser_result<impl_t, ScannerT>::type result_t;
            return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  uint_parser/int_parser instantiations
    //
    ///////////////////////////////////////////////////////////////////////////
    int_parser<int> const
        int_p   = int_parser<int>();

    uint_parser<unsigned> const
        uint_p  = uint_parser<unsigned>();

    uint_parser<unsigned, 2> const
        bin_p   = uint_parser<unsigned, 2>();

    uint_parser<unsigned, 8> const
        oct_p   = uint_parser<unsigned, 8>();

    uint_parser<unsigned, 16> const
        hex_p   = uint_parser<unsigned, 16>();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  sign_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    namespace impl
    {
        //  Utility to extract the prefix sign ('-' | '+')
        template <typename ScannerT>
        bool extract_sign(ScannerT const& scan, std::size_t& count);
    }

    struct sign_parser : public parser<sign_parser>
    {
        typedef sign_parser self_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename match_result<ScannerT, bool>::type type;
        };

        sign_parser() {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            if (!scan.at_end())
            {
                std::size_t length;
                typename ScannerT::iterator_t save(scan.first);
                bool neg = impl::extract_sign(scan, length);
                if (length)
                    return scan.create_match(1, neg, save, scan.first);
            }
            return scan.no_match();
        }
    };

    sign_parser const sign_p = sign_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  default real number policies
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename T>
    struct ureal_parser_policies
    {
        // trailing dot policy suggested suggested by Gustavo Guerra
        BOOST_STATIC_CONSTANT(bool, allow_leading_dot = true);
        BOOST_STATIC_CONSTANT(bool, allow_trailing_dot = true);
        BOOST_STATIC_CONSTANT(bool, expect_dot = false);

        typedef uint_parser<T, 10, 1, -1>   uint_parser_t;
        typedef int_parser<T, 10, 1, -1>    int_parser_t;

        template <typename ScannerT>
        static typename match_result<ScannerT, nil_t>::type
        parse_sign(ScannerT& scan)
        {
            return scan.no_match();
        }

        template <typename ScannerT>
        static typename parser_result<uint_parser_t, ScannerT>::type
        parse_n(ScannerT& scan)
        {
            return uint_parser_t().parse(scan);
        }

        template <typename ScannerT>
        static typename parser_result<chlit<>, ScannerT>::type
        parse_dot(ScannerT& scan)
        {
            return ch_p('.').parse(scan);
        }

        template <typename ScannerT>
        static typename parser_result<uint_parser_t, ScannerT>::type
        parse_frac_n(ScannerT& scan)
        {
            return uint_parser_t().parse(scan);
        }

        template <typename ScannerT>
        static typename parser_result<chlit<>, ScannerT>::type
        parse_exp(ScannerT& scan)
        {
            return as_lower_d['e'].parse(scan);
        }

        template <typename ScannerT>
        static typename parser_result<int_parser_t, ScannerT>::type
        parse_exp_n(ScannerT& scan)
        {
            return int_parser_t().parse(scan);
        }
    };

    template <typename T>
    struct real_parser_policies : public ureal_parser_policies<T>
    {
        template <typename ScannerT>
        static typename parser_result<sign_parser, ScannerT>::type
        parse_sign(ScannerT& scan)
        {
            return sign_p.parse(scan);
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  real_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <
        typename T,
        typename RealPoliciesT
    >
    struct real_parser
    :   public parser<real_parser<T, RealPoliciesT> >
    {
        typedef real_parser<T, RealPoliciesT> self_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename match_result<ScannerT, T>::type type;
        };

        real_parser() {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result<self_t, ScannerT>::type result_t;
            return impl::real_parser_impl<result_t, T, RealPoliciesT>::parse(scan);
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  real_parser instantiations
    //
    ///////////////////////////////////////////////////////////////////////////
    real_parser<double, ureal_parser_policies<double> > const
        ureal_p     = real_parser<double, ureal_parser_policies<double> >();

    real_parser<double, real_parser_policies<double> > const
        real_p      = real_parser<double, real_parser_policies<double> >();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  strict reals (do not allow plain integers (no decimal point))
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename T>
    struct strict_ureal_parser_policies : public ureal_parser_policies<T>
    {
        BOOST_STATIC_CONSTANT(bool, expect_dot = true);
    };

    template <typename T>
    struct strict_real_parser_policies : public real_parser_policies<T>
    {
        BOOST_STATIC_CONSTANT(bool, expect_dot = true);
    };

    real_parser<double, strict_ureal_parser_policies<double> > const
        strict_ureal_p
            = real_parser<double, strict_ureal_parser_policies<double> >();

    real_parser<double, strict_real_parser_policies<double> > const
        strict_real_p
            = real_parser<double, strict_real_parser_policies<double> >();

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace BOOST_SPIRIT_CLASSIC_NS

#endif


code:
/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    Copyright (c) 2003 Martin Wille
    http://spirit.sourceforge.net/

  Distributed under the Boost Software License, Version 1.0. (See accompanying
  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_PRIMITIVES_HPP)
#define BOOST_SPIRIT_PRIMITIVES_HPP

#include <boost/ref.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/assert.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/impl/directives.ipp>
#include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp>

#ifdef BOOST_MSVC
#pragma warning (push)
#pragma warning(disable : 4512)
#endif

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    ///////////////////////////////////////////////////////////////////////////
    //
    //  char_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename DerivedT>
    struct char_parser : public parser<DerivedT>
    {
        typedef DerivedT self_t;
        template <typename ScannerT>
        struct result
        {
            typedef typename match_result<
                ScannerT,
                typename ScannerT::value_t
            >::type type;
        };

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename ScannerT::value_t value_t;
            typedef typename ScannerT::iterator_t iterator_t;

            if (!scan.at_end())
            {
                value_t ch = *scan;
                if (this->derived().test(ch))
                {
                    iterator_t save(scan.first);
                    ++scan.first;
                    return scan.create_match(1, ch, save, scan.first);
                }
            }
            return scan.no_match();
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  negation of char_parsers
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename PositiveT>
    struct negated_char_parser
    : public char_parser<negated_char_parser<PositiveT> >
    {
        typedef negated_char_parser<PositiveT> self_t;
        typedef PositiveT positive_t;

        negated_char_parser(positive_t const& p)
        : positive(p.derived()) {}

        template <typename T>
        bool test(T ch) const
        {
            return !positive.test(ch);
        }

        positive_t const positive;
    };

    template <typename ParserT>
    inline negated_char_parser<ParserT>
    operator~(char_parser<ParserT> const& p)
    {
        return negated_char_parser<ParserT>(p.derived());
    }

    template <typename ParserT>
    inline ParserT
    operator~(negated_char_parser<ParserT> const& n)
    {
        return n.positive;
    }

    ///////////////////////////////////////////////////////////////////////////
    //
    //  chlit class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename CharT = char>
    struct chlit : public char_parser<chlit<CharT> >
    {
        chlit(CharT ch_)
        : ch(ch_) {}

        template <typename T>
        bool test(T ch_) const
        {
            return ch_ == ch;
        }

        CharT   ch;
    };

    template <typename CharT>
    inline chlit<CharT>
    ch_p(CharT ch)
    {
        return chlit<CharT>(ch);
    }

    // This should take care of ch_p("a") "bugs"
    template <typename CharT, std::size_t N>
    inline chlit<CharT>
    ch_p(CharT const (& str)[N])
    {
        //  ch_p's argument should be a single character or a null-terminated
        //  string with a single character
        BOOST_STATIC_ASSERT(N < 3);
        return chlit<CharT>(str[0]);
    }

    ///////////////////////////////////////////////////////////////////////////
    //
    //  range class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename CharT = char>
    struct range : public char_parser<range<CharT> >
    {
        range(CharT first_, CharT last_)
        : first(first_), last(last_)
        {
            BOOST_SPIRIT_ASSERT(!(last < first));
        }

        template <typename T>
        bool test(T ch) const
        {
            return !(CharT(ch) < first) && !(last < CharT(ch));
        }

        CharT   first;
        CharT   last;
    };

    template <typename CharT>
    inline range<CharT>
    range_p(CharT first, CharT last)
    {
        return range<CharT>(first, last);
    }

    ///////////////////////////////////////////////////////////////////////////
    //
    //  chseq class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename IteratorT = char const*>
    class chseq : public parser<chseq<IteratorT> >
    {
    public:

        typedef chseq<IteratorT> self_t;

        chseq(IteratorT first_, IteratorT last_)
        : first(first_), last(last_) {}

        chseq(IteratorT first_)
        : first(first_), last(impl::get_last(first_)) {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename boost::unwrap_reference<IteratorT>::type striter_t;
            typedef typename parser_result<self_t, ScannerT>::type result_t;
            return impl::string_parser_parse<result_t>(
                striter_t(first),
                striter_t(last),
                scan);
        }

    private:

        IteratorT first;
        IteratorT last;
    };

    template <typename CharT>
    inline chseq<CharT const*>
    chseq_p(CharT const* str)
    {
        return chseq<CharT const*>(str);
    }

    template <typename IteratorT>
    inline chseq<IteratorT>
    chseq_p(IteratorT first, IteratorT last)
    {
        return chseq<IteratorT>(first, last);
    }

    ///////////////////////////////////////////////////////////////////////////
    //
    //  strlit class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename IteratorT = char const*>
    class strlit : public parser<strlit<IteratorT> >
    {
    public:

        typedef strlit<IteratorT> self_t;

        strlit(IteratorT first, IteratorT last)
        : seq(first, last) {}

        strlit(IteratorT first)
        : seq(first) {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result<self_t, ScannerT>::type result_t;
            return impl::contiguous_parser_parse<result_t>
                (seq, scan, scan);
        }

    private:

        chseq<IteratorT> seq;
    };

    template <typename CharT>
    inline strlit<CharT const*>
    str_p(CharT const* str)
    {
        return strlit<CharT const*>(str);
    }

    template <typename CharT>
    inline strlit<CharT *>
    str_p(CharT * str)
    {
        return strlit<CharT *>(str);
    }

    template <typename IteratorT>
    inline strlit<IteratorT>
    str_p(IteratorT first, IteratorT last)
    {
        return strlit<IteratorT>(first, last);
    }

    // This should take care of str_p('a') "bugs"
    template <typename CharT>
    inline chlit<CharT>
    str_p(CharT ch)
    {
        return chlit<CharT>(ch);
    }

    ///////////////////////////////////////////////////////////////////////////
    //
    //  nothing_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct nothing_parser : public parser<nothing_parser>
    {
        typedef nothing_parser self_t;

        nothing_parser() {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            return scan.no_match();
        }
    };

    nothing_parser const nothing_p = nothing_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  anychar_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct anychar_parser : public char_parser<anychar_parser>
    {
        typedef anychar_parser self_t;

        anychar_parser() {}

        template <typename CharT>
        bool test(CharT) const
        {
            return true;
        }
    };

    anychar_parser const anychar_p = anychar_parser();

    inline nothing_parser
    operator~(anychar_parser)
    {
        return nothing_p;
    }

    ///////////////////////////////////////////////////////////////////////////
    //
    //  alnum_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct alnum_parser : public char_parser<alnum_parser>
    {
        typedef alnum_parser self_t;

        alnum_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::isalnum_(ch);
        }
    };

    alnum_parser const alnum_p = alnum_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  alpha_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct alpha_parser : public char_parser<alpha_parser>
    {
        typedef alpha_parser self_t;

        alpha_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::isalpha_(ch);
        }
    };

    alpha_parser const alpha_p = alpha_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  cntrl_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct cntrl_parser : public char_parser<cntrl_parser>
    {
        typedef cntrl_parser self_t;

        cntrl_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::iscntrl_(ch);
        }
    };

    cntrl_parser const cntrl_p = cntrl_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  digit_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct digit_parser : public char_parser<digit_parser>
    {
        typedef digit_parser self_t;

        digit_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::isdigit_(ch);
        }
    };

    digit_parser const digit_p = digit_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  graph_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct graph_parser : public char_parser<graph_parser>
    {
        typedef graph_parser self_t;

        graph_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::isgraph_(ch);
        }
    };

    graph_parser const graph_p = graph_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  lower_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct lower_parser : public char_parser<lower_parser>
    {
        typedef lower_parser self_t;

        lower_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::islower_(ch);
        }
    };

    lower_parser const lower_p = lower_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  print_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct print_parser : public char_parser<print_parser>
    {
        typedef print_parser self_t;

        print_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::isprint_(ch);
        }
    };

    print_parser const print_p = print_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  punct_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct punct_parser : public char_parser<punct_parser>
    {
        typedef punct_parser self_t;

        punct_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::ispunct_(ch);
        }
    };

    punct_parser const punct_p = punct_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  blank_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct blank_parser : public char_parser<blank_parser>
    {
        typedef blank_parser self_t;

        blank_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::isblank_(ch);
        }
    };

    blank_parser const blank_p = blank_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  space_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct space_parser : public char_parser<space_parser>
    {
        typedef space_parser self_t;

        space_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::isspace_(ch);
        }
    };

    space_parser const space_p = space_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  upper_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct upper_parser : public char_parser<upper_parser>
    {
        typedef upper_parser self_t;

        upper_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::isupper_(ch);
        }
    };

    upper_parser const upper_p = upper_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  xdigit_parser class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct xdigit_parser : public char_parser<xdigit_parser>
    {
        typedef xdigit_parser self_t;

        xdigit_parser() {}

        template <typename CharT>
        bool test(CharT ch) const
        {
            return impl::isxdigit_(ch);
        }
    };

    xdigit_parser const xdigit_p = xdigit_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  eol_parser class (contributed by Martin Wille)
    //
    ///////////////////////////////////////////////////////////////////////////
    struct eol_parser : public parser<eol_parser>
    {
        typedef eol_parser self_t;

        eol_parser() {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typename ScannerT::iterator_t save = scan.first;
            std::size_t len = 0;

            if (!scan.at_end() && *scan == '\r')    // CR
            {
                ++scan.first;
                ++len;
            }

            // Don't call skipper here
            if (scan.first != scan.last && *scan == '\n')    // LF
            {
                ++scan.first;
                ++len;
            }

            if (len)
                return scan.create_match(len, nil_t(), save, scan.first);
            return scan.no_match();
        }
    };

    eol_parser const eol_p = eol_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  end_parser class (suggested by Markus Schoepflin)
    //
    ///////////////////////////////////////////////////////////////////////////
    struct end_parser : public parser<end_parser>
    {
        typedef end_parser self_t;

        end_parser() {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            if (scan.at_end())
                return scan.empty_match();
            return scan.no_match();
        }
    };

    end_parser const end_p = end_parser();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  the pizza_p parser :-)
    //
    ///////////////////////////////////////////////////////////////////////////
    inline strlit<char const*> const
    pizza_p(char const* your_favorite_pizza)
    {
        return your_favorite_pizza;
    }

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace BOOST_SPIRIT_CLASSIC_NS

#ifdef BOOST_MSVC
#pragma warning (pop)
#endif

#endif


code:
/*=============================================================================
    Copyright (c) 2003 Joel de Guzman
    http://spirit.sourceforge.net/

  Distributed under the Boost Software License, Version 1.0. (See accompanying
  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_SAFE_BOOL_HPP)
#define BOOST_SPIRIT_SAFE_BOOL_HPP

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/spirit/home/classic/namespace.hpp>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    namespace impl
    {
        template <typename T>
        struct no_base {};

        template <typename T>
        struct safe_bool_impl
        {
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
            void stub(T*) {};
            typedef void (safe_bool_impl::*type)(T*);
#else
            typedef T* TP; // workaround to make parsing easier
            TP stub;
            typedef TP safe_bool_impl::*type;
#endif
        };
    }

    template <typename DerivedT, typename BaseT = impl::no_base<DerivedT> >
    struct safe_bool : BaseT
    {
    private:
        typedef impl::safe_bool_impl<DerivedT> impl_t;
        typedef typename impl_t::type bool_type;

    public:
        operator bool_type() const
        {
            return static_cast<const DerivedT*>(this)->operator_bool() ?
                &impl_t::stub : 0;
        }

        operator bool_type()
        {
            return static_cast<DerivedT*>(this)->operator_bool() ?
                &impl_t::stub : 0;
        }
    };

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}}

#endif


code:
/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt)
============================================================================*/
#if !defined(BOOST_SPIRIT_SKIPPER_IPP)
#define BOOST_SPIRIT_SKIPPER_IPP

///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    struct space_parser;
    template <typename BaseT>
    struct no_skipper_iteration_policy;

    namespace impl
    {
        template <typename ST, typename ScannerT, typename BaseT>
        inline void
        skipper_skip(
            ST const& s,
            ScannerT const& scan,
            skipper_iteration_policy<BaseT> const&)
        {
            typedef scanner_policies<
                no_skipper_iteration_policy<
                    BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
                BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
                BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
            > policies_t;

            scanner<BOOST_DEDUCED_TYPENAME ScannerT::iterator_t, policies_t>
                scan2(scan.first, scan.last, policies_t(scan));
            typedef typename ScannerT::iterator_t iterator_t;

            for (;;)
            {
                iterator_t save = scan.first;
                if (!s.parse(scan2))
                {
                    scan.first = save;
                    break;
                }
            }
        }

        template <typename ST, typename ScannerT, typename BaseT>
        inline void
        skipper_skip(
            ST const& s,
            ScannerT const& scan,
            no_skipper_iteration_policy<BaseT> const&)
        {
            for (;;)
            {
                typedef typename ScannerT::iterator_t iterator_t;
                iterator_t save = scan.first;
                if (!s.parse(scan))
                {
                    scan.first = save;
                    break;
                }
            }
        }

        template <typename ST, typename ScannerT>
        inline void
        skipper_skip(
            ST const& s,
            ScannerT const& scan,
            iteration_policy const&)
        {
            for (;;)
            {
                typedef typename ScannerT::iterator_t iterator_t;
                iterator_t save = scan.first;
                if (!s.parse(scan))
                {
                    scan.first = save;
                    break;
                }
            }
        }

        template <typename SkipT>
        struct phrase_parser
        {
            template <typename IteratorT, typename ParserT>
            static parse_info<IteratorT>
            parse(
                IteratorT const&    first_,
                IteratorT const&    last,
                ParserT const&      p,
                SkipT const&        skip)
            {
                typedef skip_parser_iteration_policy<SkipT> iter_policy_t;
                typedef scanner_policies<iter_policy_t> scanner_policies_t;
                typedef scanner<IteratorT, scanner_policies_t> scanner_t;

                iter_policy_t iter_policy(skip);
                scanner_policies_t policies(iter_policy);
                IteratorT first = first_;
                scanner_t scan(first, last, policies);
                match<nil_t> hit = p.parse(scan);
                return parse_info<IteratorT>(
                    first, hit, hit && (first == last),
                    hit.length());
            }
        };

        template <>
        struct phrase_parser<space_parser>
        {
            template <typename IteratorT, typename ParserT>
            static parse_info<IteratorT>
            parse(
                IteratorT const&    first_,
                IteratorT const&    last,
                ParserT const&      p,
                space_parser const&)
            {
                typedef skipper_iteration_policy<> iter_policy_t;
                typedef scanner_policies<iter_policy_t> scanner_policies_t;
                typedef scanner<IteratorT, scanner_policies_t> scanner_t;

                IteratorT first = first_;
                scanner_t scan(first, last);
                match<nil_t> hit = p.parse(scan);
                return parse_info<IteratorT>(
                    first, hit, hit && (first == last),
                    hit.length());
            }
        };
    }

    ///////////////////////////////////////////////////////////////////////////
    //
    //  Free parse functions using the skippers
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename IteratorT, typename ParserT, typename SkipT>
    inline parse_info<IteratorT>
    parse(
        IteratorT const&        first,
        IteratorT const&        last,
        parser<ParserT> const&  p,
        parser<SkipT> const&    skip)
    {
        return impl::phrase_parser<SkipT>::
            parse(first, last, p.derived(), skip.derived());
    }

    ///////////////////////////////////////////////////////////////////////////
    //
    //  Parse function for null terminated strings using the skippers
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename CharT, typename ParserT, typename SkipT>
    inline parse_info<CharT const*>
    parse(
        CharT const*            str,
        parser<ParserT> const&  p,
        parser<SkipT> const&    skip)
    {
        CharT const* last = str;
        while (*last)
            last++;
        return parse(str, last, p, skip);
    }

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace boost::spirit

#endif


code:
/*=============================================================================
    Copyright (c) 1998-2002 Joel de Guzman
    http://spirit.sourceforge.net/

  Distributed under the Boost Software License, Version 1.0. (See accompanying
  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_SCANNER_HPP)
#define BOOST_SPIRIT_SCANNER_HPP

#include <iterator>
#include <boost/config.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/match.hpp>
#include <boost/spirit/home/classic/core/non_terminal/parser_id.hpp>
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits

#include <boost/spirit/home/classic/core/scanner/scanner_fwd.hpp>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    ///////////////////////////////////////////////////////////////////////////
    //
    //  iteration_policy class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct iteration_policy
    {
        template <typename ScannerT>
        void
        advance(ScannerT const& scan) const
        {
            ++scan.first;
        }

        template <typename ScannerT>
        bool at_end(ScannerT const& scan) const
        {
            return scan.first == scan.last;
        }

        template <typename T>
        T filter(T ch) const
        {
            return ch;
        }

        template <typename ScannerT>
        typename ScannerT::ref_t
        get(ScannerT const& scan) const
        {
            return *scan.first;
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  match_policy class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct match_policy
    {
        template <typename T>
        struct result { typedef match<T> type; };

        const match<nil_t>
        no_match() const
        {
            return match<nil_t>();
        }

        const match<nil_t>
        empty_match() const
        {
            return match<nil_t>(0, nil_t());
        }

        template <typename AttrT, typename IteratorT>
        match<AttrT>
        create_match(
            std::size_t         length,
            AttrT const&        val,
            IteratorT const&    /*first*/,
            IteratorT const&    /*last*/) const
        {
            return match<AttrT>(length, val);
        }

        template <typename MatchT, typename IteratorT>
        void group_match(
            MatchT&             /*m*/,
            parser_id const&    /*id*/,
            IteratorT const&    /*first*/,
            IteratorT const&    /*last*/) const {}

        template <typename Match1T, typename Match2T>
        void concat_match(Match1T& l, Match2T const& r) const
        {
            l.concat(r);
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  match_result class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename MatchPolicyT, typename T>
    struct match_result
    {
        typedef typename MatchPolicyT::template result<T>::type type;
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  action_policy class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename AttrT>
    struct attributed_action_policy
    {
        template <typename ActorT, typename IteratorT>
        static void
        call(
            ActorT const& actor,
            AttrT& val,
            IteratorT const&,
            IteratorT const&)
        {
            actor(val);
        }
    };

    //////////////////////////////////
    template <>
    struct attributed_action_policy<nil_t>
    {
        template <typename ActorT, typename IteratorT>
        static void
        call(
            ActorT const& actor,
            nil_t,
            IteratorT const& first,
            IteratorT const& last)
        {
            actor(first, last);
        }
    };

    //////////////////////////////////
    struct action_policy
    {
        template <typename ActorT, typename AttrT, typename IteratorT>
        void
        do_action(
            ActorT const&       actor,
            AttrT&              val,
            IteratorT const&    first,
            IteratorT const&    last) const
        {
            attributed_action_policy<AttrT>::call(actor, val, first, last);
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  scanner_policies class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <
        typename IterationPolicyT,
        typename MatchPolicyT,
        typename ActionPolicyT>
    struct scanner_policies :
        public IterationPolicyT,
        public MatchPolicyT,
        public ActionPolicyT
    {
        typedef IterationPolicyT    iteration_policy_t;
        typedef MatchPolicyT        match_policy_t;
        typedef ActionPolicyT       action_policy_t;

        scanner_policies(
            IterationPolicyT const& i_policy = IterationPolicyT(),
            MatchPolicyT const&     m_policy = MatchPolicyT(),
            ActionPolicyT const&    a_policy = ActionPolicyT())
        : IterationPolicyT(i_policy)
        , MatchPolicyT(m_policy)
        , ActionPolicyT(a_policy) {}

        template <typename ScannerPoliciesT>
        scanner_policies(ScannerPoliciesT const& policies)
        : IterationPolicyT(policies)
        , MatchPolicyT(policies)
        , ActionPolicyT(policies) {}
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  scanner_policies_base class: the base class of all scanners
    //
    ///////////////////////////////////////////////////////////////////////////
    struct scanner_base {};

    ///////////////////////////////////////////////////////////////////////////
    //
    //  scanner class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <
        typename IteratorT,
        typename PoliciesT>
    class scanner : public PoliciesT, public scanner_base
    {
    public:

        typedef IteratorT iterator_t;
        typedef PoliciesT policies_t;

        typedef typename boost::detail::
            iterator_traits<IteratorT>::value_type value_t;
        typedef typename boost::detail::
            iterator_traits<IteratorT>::reference ref_t;
        typedef typename boost::
            call_traits<IteratorT>::param_type iter_param_t;

        scanner(
            IteratorT&          first_,
            iter_param_t        last_,
            PoliciesT const&    policies = PoliciesT())
        : PoliciesT(policies), first(first_), last(last_)
        {
            at_end();
        }

        scanner(scanner const& other)
        : PoliciesT(other), first(other.first), last(other.last) {}

        scanner(scanner const& other, IteratorT& first_)
        : PoliciesT(other), first(first_), last(other.last) {}

        template <typename PoliciesT1>
        scanner(scanner<IteratorT, PoliciesT1> const& other)
        : PoliciesT(other), first(other.first), last(other.last) {}

        bool
        at_end() const
        {
            typedef typename PoliciesT::iteration_policy_t iteration_policy_type;
            return iteration_policy_type::at_end(*this);
        }

        value_t
        operator*() const
        {
            typedef typename PoliciesT::iteration_policy_t iteration_policy_type;
            return iteration_policy_type::filter(iteration_policy_type::get(*this));
        }

        scanner const&
        operator++() const
        {
            typedef typename PoliciesT::iteration_policy_t iteration_policy_type;
            iteration_policy_type::advance(*this);
            return *this;
        }

        template <typename PoliciesT2>
        struct rebind_policies
        {
            typedef scanner<IteratorT, PoliciesT2> type;
        };

        template <typename PoliciesT2>
        scanner<IteratorT, PoliciesT2>
        change_policies(PoliciesT2 const& policies) const
        {
            return scanner<IteratorT, PoliciesT2>(first, last, policies);
        }

        template <typename IteratorT2>
        struct rebind_iterator
        {
            typedef scanner<IteratorT2, PoliciesT> type;
        };

        template <typename IteratorT2>
        scanner<IteratorT2, PoliciesT>
        change_iterator(IteratorT2 const& first_, IteratorT2 const &last_) const
        {
            return scanner<IteratorT2, PoliciesT>(first_, last_, *this);
        }

        IteratorT& first;
        IteratorT const last;

    private:

        scanner&
        operator=(scanner const& other);
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  rebind_scanner_policies class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename ScannerT, typename PoliciesT>
    struct rebind_scanner_policies
    {
        typedef typename ScannerT::template
            rebind_policies<PoliciesT>::type type;
    };

    //////////////////////////////////
    template <typename ScannerT, typename IteratorT>
    struct rebind_scanner_iterator
    {
        typedef typename ScannerT::template
            rebind_iterator<IteratorT>::type type;
    };

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}}

#endif


code:
/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    http://spirit.sourceforge.net/

  Distributed under the Boost Software License, Version 1.0. (See accompanying
  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_SKIPPER_HPP)
#define BOOST_SPIRIT_SKIPPER_HPP

///////////////////////////////////////////////////////////////////////////////
#include <cctype>

#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/scanner/scanner.hpp>
#include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp>

#include <boost/spirit/home/classic/core/scanner/skipper_fwd.hpp>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    ///////////////////////////////////////////////////////////////////////////
    //
    //  skipper_iteration_policy class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename BaseT>
    struct skipper_iteration_policy : public BaseT
    {
        typedef BaseT base_t;

        skipper_iteration_policy()
        : BaseT() {}

        template <typename PolicyT>
        skipper_iteration_policy(PolicyT const& other)
        : BaseT(other) {}

        template <typename ScannerT>
        void
        advance(ScannerT const& scan) const
        {
            BaseT::advance(scan);
            scan.skip(scan);
        }

        template <typename ScannerT>
        bool
        at_end(ScannerT const& scan) const
        {
            scan.skip(scan);
            return BaseT::at_end(scan);
        }

        template <typename ScannerT>
        void
        skip(ScannerT const& scan) const
        {
            while (!BaseT::at_end(scan) && impl::isspace_(BaseT::get(scan)))
                BaseT::advance(scan);
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  no_skipper_iteration_policy class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename BaseT>
    struct no_skipper_iteration_policy : public BaseT
    {
        typedef BaseT base_t;

        no_skipper_iteration_policy()
        : BaseT() {}

        template <typename PolicyT>
        no_skipper_iteration_policy(PolicyT const& other)
        : BaseT(other) {}

        template <typename ScannerT>
        void
        skip(ScannerT const& /*scan*/) const {}
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  skip_parser_iteration_policy class
    //
    ///////////////////////////////////////////////////////////////////////////
    namespace impl
    {
        template <typename ST, typename ScannerT, typename BaseT>
        void
        skipper_skip(
            ST const& s,
            ScannerT const& scan,
            skipper_iteration_policy<BaseT> const&);

        template <typename ST, typename ScannerT, typename BaseT>
        void
        skipper_skip(
            ST const& s,
            ScannerT const& scan,
            no_skipper_iteration_policy<BaseT> const&);

        template <typename ST, typename ScannerT>
        void
        skipper_skip(
            ST const& s,
            ScannerT const& scan,
            iteration_policy const&);
    }

    template <typename ParserT, typename BaseT>
    class skip_parser_iteration_policy : public skipper_iteration_policy<BaseT>
    {
    public:

        typedef skipper_iteration_policy<BaseT> base_t;

        skip_parser_iteration_policy(
            ParserT const& skip_parser,
            base_t const& base = base_t())
        : base_t(base), subject(skip_parser) {}

        template <typename PolicyT>
        skip_parser_iteration_policy(PolicyT const& other)
        : base_t(other), subject(other.skipper()) {}

        template <typename ScannerT>
        void
        skip(ScannerT const& scan) const
        {
            impl::skipper_skip(subject, scan, scan);
        }

        ParserT const&
        skipper() const
        {
            return subject;
        }

    private:

        ParserT const& subject;
    };

    ///////////////////////////////////////////////////////////////////////////////
    //
    //  Free parse functions using the skippers
    //
    ///////////////////////////////////////////////////////////////////////////////
    template <typename IteratorT, typename ParserT, typename SkipT>
    parse_info<IteratorT>
    parse(
        IteratorT const&        first,
        IteratorT const&        last,
        parser<ParserT> const&  p,
        parser<SkipT> const&    skip);

    ///////////////////////////////////////////////////////////////////////////////
    //
    //  Parse function for null terminated strings using the skippers
    //
    ///////////////////////////////////////////////////////////////////////////////
    template <typename CharT, typename ParserT, typename SkipT>
    parse_info<CharT const*>
    parse(
        CharT const*            str,
        parser<ParserT> const&  p,
        parser<SkipT> const&    skip);

    ///////////////////////////////////////////////////////////////////////////////
    //
    //  phrase_scanner_t and wide_phrase_scanner_t
    //
    //      The most common scanners. Use these typedefs when you need
    //      a scanner that skips white spaces.
    //
    ///////////////////////////////////////////////////////////////////////////////
    typedef skipper_iteration_policy<>                  iter_policy_t;
    typedef scanner_policies<iter_policy_t>             scanner_policies_t;
    typedef scanner<char const*, scanner_policies_t>    phrase_scanner_t;
    typedef scanner<wchar_t const*, scanner_policies_t> wide_phrase_scanner_t;

    ///////////////////////////////////////////////////////////////////////////////

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace BOOST_SPIRIT_CLASSIC_NS

#include <boost/spirit/home/classic/core/scanner/impl/skipper.ipp>
#endif


code:
/*=============================================================================
    Copyright (c) 2006 Tobias Schwinger
    http://spirit.sourceforge.net/

  Distributed under the Boost Software License, Version 1.0. (See accompanying
  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_SKIPPER_FWD_HPP)
#define BOOST_SPIRIT_SKIPPER_FWD_HPP

#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/scanner/scanner_fwd.hpp>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    template <typename BaseT = iteration_policy>
    struct skipper_iteration_policy;

    template <typename BaseT = iteration_policy>
    struct no_skipper_iteration_policy;

    template <typename ParserT, typename BaseT = iteration_policy>
    class skip_parser_iteration_policy;

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace BOOST_SPIRIT_CLASSIC_NS

#endif


code:
/*=============================================================================
    Copyright (c) 2001-2003 Joel de Guzman
    Copyright (c) 2002-2003 Hartmut Kaiser
    Copyright (c) 2003 Gustavo Guerra
    http://spirit.sourceforge.net/

  Distributed under the Boost Software License, Version 1.0. (See accompanying
  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_DEBUG_NODE_HPP)
#define BOOST_SPIRIT_DEBUG_NODE_HPP

#if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP)
#error "You must include boost/spirit/debug.hpp, not boost/spirit/debug/debug_node.hpp"
#endif

#if defined(BOOST_SPIRIT_DEBUG)

#include <string>

#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/primitives/primitives.hpp> // for iscntrl_

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

///////////////////////////////////////////////////////////////////////////////
//
//  Debug helper classes for rules, which ensure maximum non-intrusiveness of
//  the Spirit debug support
//
///////////////////////////////////////////////////////////////////////////////

namespace impl {

    struct token_printer_aux_for_chars
    {
        template<typename CharT>
        static void print(std::ostream& o, CharT c)
        {
            if (c == static_cast<CharT>('\a'))
                o << "\\a";

            else if (c == static_cast<CharT>('\b'))
                o << "\\b";

            else if (c == static_cast<CharT>('\f'))
                o << "\\f";

            else if (c == static_cast<CharT>('\n'))
                o << "\\n";

            else if (c == static_cast<CharT>('\r'))
                o << "\\r";

            else if (c == static_cast<CharT>('\t'))
                o << "\\t";

            else if (c == static_cast<CharT>('\v'))
                o << "\\v";

            else if (iscntrl_(c))
                o << "\\" << static_cast<int>(c);

            else
                o << static_cast<char>(c);
        }
    };

    // for token types where the comparison with char constants wouldn't work
    struct token_printer_aux_for_other_types
    {
        template<typename CharT>
        static void print(std::ostream& o, CharT c)
        {
            o << c;
        }
    };

    template <typename CharT>
    struct token_printer_aux
    :   mpl::if_<
            mpl::and_<
                is_convertible<CharT, char>,
                is_convertible<char, CharT> >,
            token_printer_aux_for_chars,
            token_printer_aux_for_other_types
        >::type
    {
    };

    template<typename CharT>
    inline void token_printer(std::ostream& o, CharT c)
    {
    #if !defined(BOOST_SPIRIT_DEBUG_TOKEN_PRINTER)

        token_printer_aux<CharT>::print(o, c);

    #else

        BOOST_SPIRIT_DEBUG_TOKEN_PRINTER(o, c);

    #endif
    }

///////////////////////////////////////////////////////////////////////////////
//
//  Dump infos about the parsing state of a rule
//
///////////////////////////////////////////////////////////////////////////////

#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
    template <typename IteratorT>
    inline void
    print_node_info(bool hit, int level, bool close, std::string const& name,
        IteratorT first, IteratorT last)
    {
        if (!name.empty())
        {
            for (int i = 0; i < level; ++i)
                BOOST_SPIRIT_DEBUG_OUT << "  ";
            if (close)
            {
                if (hit)
                    BOOST_SPIRIT_DEBUG_OUT << "/";
                else
                    BOOST_SPIRIT_DEBUG_OUT << "#";
            }
            BOOST_SPIRIT_DEBUG_OUT << name << ":\t\"";
            IteratorT iter = first;
            IteratorT ilast = last;
            for (int j = 0; j < BOOST_SPIRIT_DEBUG_PRINT_SOME; ++j)
            {
                if (iter == ilast)
                    break;

                token_printer(BOOST_SPIRIT_DEBUG_OUT, *iter);
                ++iter;
            }
            BOOST_SPIRIT_DEBUG_OUT << "\"\n";
        }
    }
#endif  // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES

#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
    template <typename ResultT>
    inline ResultT &
    print_closure_info(ResultT &hit, int level, std::string const& name)
    {
        if (!name.empty())
        {
            for (int i = 0; i < level-1; ++i)
                BOOST_SPIRIT_DEBUG_OUT << "  ";

        // for now, print out the return value only
            BOOST_SPIRIT_DEBUG_OUT << "^" << name << ":\t";
            if (hit.has_valid_attribute())
                BOOST_SPIRIT_DEBUG_OUT << hit.value();
            else
                BOOST_SPIRIT_DEBUG_OUT << "undefined attribute";
            BOOST_SPIRIT_DEBUG_OUT << "\n";
        }
        return hit;
    }
#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES

}

///////////////////////////////////////////////////////////////////////////////
//
//  Implementation note: The parser_context_linker, parser_scanner_linker and
//  closure_context_linker classes are wrapped by a PP constant to allow
//  redefinition of this classes outside of Spirit
//
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
#define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED

    ///////////////////////////////////////////////////////////////////////////
    //
    //  parser_context_linker is a debug wrapper for the ContextT template
    //  parameter of the rule<>, subrule<> and the grammar<> classes
    //
    ///////////////////////////////////////////////////////////////////////////
    template<typename ContextT>
    struct parser_context_linker : public ContextT
    {
        typedef ContextT base_t;

        template <typename ParserT>
        parser_context_linker(ParserT const& p)
        : ContextT(p) {}

        template <typename ParserT, typename ScannerT>
        void pre_parse(ParserT const& p, ScannerT &scan)
        {
            this->base_t::pre_parse(p, scan);

#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
            if (trace_parser(p.derived())) {
                impl::print_node_info(
                    false,
                    scan.get_level(),
                    false,
                    parser_name(p.derived()),
                    scan.first,
                    scan.last);
            }
            scan.get_level()++;
#endif  // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
        }

        template <typename ResultT, typename ParserT, typename ScannerT>
        ResultT& post_parse(ResultT& hit, ParserT const& p, ScannerT &scan)
        {
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
            --scan.get_level();
            if (trace_parser(p.derived())) {
                impl::print_node_info(
                    hit,
                    scan.get_level(),
                    true,
                    parser_name(p.derived()),
                    scan.first,
                    scan.last);
            }
#endif  // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES

            return this->base_t::post_parse(hit, p, scan);
        }
    };

#endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)

#if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
#define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED

///////////////////////////////////////////////////////////////////////////////
//  This class is to avoid linker problems and to ensure a real singleton
//  'level' variable
    struct debug_support
    {
        int& get_level()
        {
            static int level = 0;
            return level;
        }
    };

    template<typename ScannerT>
    struct parser_scanner_linker : public ScannerT
    {
        parser_scanner_linker(ScannerT const &scan_) : ScannerT(scan_)
        {}

        int &get_level()
        { return debug.get_level(); }

        private: debug_support debug;
    };

#endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)

#if !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)
#define BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED

    ///////////////////////////////////////////////////////////////////////////
    //
    //  closure_context_linker is a debug wrapper for the closure template
    //  parameter of the rule<>, subrule<> and grammar classes
    //
    ///////////////////////////////////////////////////////////////////////////

    template<typename ContextT>
    struct closure_context_linker : public parser_context_linker<ContextT>
    {
        typedef parser_context_linker<ContextT> base_t;

        template <typename ParserT>
        closure_context_linker(ParserT const& p)
        : parser_context_linker<ContextT>(p) {}

        template <typename ParserT, typename ScannerT>
        void pre_parse(ParserT const& p, ScannerT &scan)
        { this->base_t::pre_parse(p, scan); }

        template <typename ResultT, typename ParserT, typename ScannerT>
        ResultT&
        post_parse(ResultT& hit, ParserT const& p, ScannerT &scan)
        {
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
            if (hit && trace_parser(p.derived())) {
            // for now, print out the return value only
                return impl::print_closure_info(
                    this->base_t::post_parse(hit, p, scan),
                    scan.get_level(),
                    parser_name(p.derived())
                );
            }
#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES

            return this->base_t::post_parse(hit, p, scan);
        }
    };

#endif // !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace BOOST_SPIRIT_CLASSIC_NS

#endif // defined(BOOST_SPIRIT_DEBUG)

#endif // !defined(BOOST_SPIRIT_DEBUG_NODE_HPP)