/*============================================================================= Copyright (c) 2001-2008 Hartmut Kaiser 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_APR_18_2008_0751PM) #define BOOST_SPIRIT_PRIMITIVES_APR_18_2008_0751PM #include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { namespace qi { /////////////////////////////////////////////////////////////////////////// // the end_director_base is a base class for various end parsers /////////////////////////////////////////////////////////////////////////// template struct end_director_base { typedef mpl::false_ stores_iterator; template struct attribute { typedef unused_type type; }; template < typename Component , typename Iterator, typename Context , typename Skipper, typename Attribute> static bool parse( Component const& /*component*/ , Iterator& first, Iterator const& last , Context& /*context*/, Skipper const& skipper , Attribute& /*attr*/) { qi::skip(first, last, skipper); return Parser::test(first, last); } // subclasses are required to implement test: template bool test(Iterator& first, Iterator const& last); }; /////////////////////////////////////////////////////////////////////////// // same as end_director_base above, but stores iterator /////////////////////////////////////////////////////////////////////////// template struct end_director_base { typedef mpl::true_ stores_iterator; template struct attribute { typedef unused_type type; }; template < typename Component , typename Iterator, typename Context , typename Skipper, typename Attribute> static bool parse( Component const& /*component*/ , Iterator& first, Iterator const& last , Context& /*context*/, Skipper const& skipper , Attribute& /*attr*/) { qi::skip(first, last, skipper); Iterator it = first; if (!Parser::test(it, last)) return false; first = it; return true; } // subclasses are required to implement test: template bool test(Iterator& first, Iterator const& last); }; /////////////////////////////////////////////////////////////////////////// // ~eoi, ~eol: 'not end of line' or 'not end of input' template struct negated_end_director : end_director_base< negated_end_director, typename Positive::director::stores_iterator > { template static bool test (Iterator& first, Iterator const& last) { return !Positive::director::test(first, last); } template static std::string what(Component const& component, Context const& ctx) { return "not " + Positive::director::what(fusion::at_c<0>(component.elements), ctx); } }; /////////////////////////////////////////////////////////////////////////// // eoi: end of input struct eoi_director : end_director_base { template static bool test (Iterator& first, Iterator const& last) { return first == last; } template static std::string what(Component const& component, Context const& ctx) { return "eoi"; } }; /////////////////////////////////////////////////////////////////////////// // the eol_director matches line endings /////////////////////////////////////////////////////////////////////////// struct eol_director : end_director_base { template static bool test (Iterator& first, Iterator const& last) { bool matched = false; if (first != last && *first == '\r') // CR { matched = true; ++first; } if (first != last && *first == '\n') // LF { matched = true; ++first; } return matched; } template static std::string what(Component const& component, Context const& ctx) { return "eol"; } }; /////////////////////////////////////////////////////////////////////////////// }}} #endif