| /*============================================================================= |
| Copyright (c) 1998-2003 Joel de Guzman |
| Copyright (c) 2001 Daniel Nuffer |
| Copyright (c) 2001 Bruce Florman |
| Copyright (c) 2002 Raghavendra Satish |
| 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_DIRECTIVES_IPP) |
| #define BOOST_SPIRIT_DIRECTIVES_IPP |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| #include <boost/spirit/home/classic/core/scanner/skipper.hpp> |
| |
| namespace boost { namespace spirit { |
| |
| BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN |
| |
| template <typename BaseT> |
| struct no_skipper_iteration_policy; |
| |
| template <typename BaseT> |
| struct inhibit_case_iteration_policy; |
| |
| template <typename A, typename B> |
| struct alternative; |
| |
| template <typename A, typename B> |
| struct longest_alternative; |
| |
| template <typename A, typename B> |
| struct shortest_alternative; |
| |
| namespace impl |
| { |
| template <typename RT, typename ST, typename ScannerT, typename BaseT> |
| inline RT |
| contiguous_parser_parse( |
| 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; |
| |
| scan.skip(scan); |
| RT hit = s.parse(scan.change_policies(policies_t(scan))); |
| // We will not do a post skip!!! |
| return hit; |
| } |
| |
| template <typename RT, typename ST, typename ScannerT, typename BaseT> |
| inline RT |
| contiguous_parser_parse( |
| ST const& s, |
| ScannerT const& scan, |
| no_skipper_iteration_policy<BaseT> const&) |
| { |
| return s.parse(scan); |
| } |
| |
| template <typename RT, typename ST, typename ScannerT> |
| inline RT |
| contiguous_parser_parse( |
| ST const& s, |
| ScannerT const& scan, |
| iteration_policy const&) |
| { |
| return s.parse(scan); |
| } |
| |
| template < |
| typename RT, |
| typename ParserT, |
| typename ScannerT, |
| typename BaseT> |
| inline RT |
| implicit_lexeme_parse( |
| ParserT const& p, |
| 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; |
| |
| scan.skip(scan); |
| RT hit = p.parse_main(scan.change_policies(policies_t(scan))); |
| // We will not do a post skip!!! |
| return hit; |
| } |
| |
| template < |
| typename RT, |
| typename ParserT, |
| typename ScannerT, |
| typename BaseT> |
| inline RT |
| implicit_lexeme_parse( |
| ParserT const& p, |
| ScannerT const& scan, |
| no_skipper_iteration_policy<BaseT> const&) |
| { |
| return p.parse_main(scan); |
| } |
| |
| template <typename RT, typename ParserT, typename ScannerT> |
| inline RT |
| implicit_lexeme_parse( |
| ParserT const& p, |
| ScannerT const& scan, |
| iteration_policy const&) |
| { |
| return p.parse_main(scan); |
| } |
| |
| template <typename RT, typename ST, typename ScannerT> |
| inline RT |
| inhibit_case_parser_parse( |
| ST const& s, |
| ScannerT const& scan, |
| iteration_policy const&) |
| { |
| typedef scanner_policies< |
| inhibit_case_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; |
| |
| return s.parse(scan.change_policies(policies_t(scan))); |
| } |
| |
| template <typename RT, typename ST, typename ScannerT, typename BaseT> |
| inline RT |
| inhibit_case_parser_parse( |
| ST const& s, |
| ScannerT const& scan, |
| inhibit_case_iteration_policy<BaseT> const&) |
| { |
| return s.parse(scan); |
| } |
| |
| #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) |
| |
| /////////////////////////////////////////////////////////////////////// |
| // |
| // from spirit 1.1 (copyright (c) 2001 Bruce Florman) |
| // various workarounds to support longest and shortest directives |
| // |
| /////////////////////////////////////////////////////////////////////// |
| template <typename T> |
| struct is_alternative |
| { |
| // Determine at compile time (without partial specialization) |
| // whether a given type is an instance of the alternative<A,B> |
| |
| static T t(); |
| template <typename A, typename B> |
| static char test_(alternative<A, B> const&); // no implementation |
| static int test_(...); // no implementation |
| enum { r = sizeof(char) == sizeof(test_(t())) }; |
| typedef mpl::bool_<r> value; |
| }; |
| |
| template <typename T> struct select_to_longest; |
| |
| template <typename T> |
| struct to_longest_alternative |
| { |
| typedef typename select_to_longest<T>::result_t result_t; |
| typedef typename select_to_longest<T>::plain_t plain_t; |
| typedef typename select_to_longest<T>::choose_t choose_t; |
| static result_t convert(T const& a); |
| }; |
| |
| template <typename T> |
| struct to_longest_generic |
| { |
| typedef T const& result_t; |
| typedef T plain_t; |
| typedef mpl::false_ choose_t; |
| }; |
| |
| template <typename T> |
| inline T const& |
| to_longest_convert(T const& a, mpl::false_) |
| { return a; } |
| |
| template <typename T> |
| struct to_longest_recursive |
| { |
| typedef typename to_longest_alternative< |
| typename T::left_t>::plain_t a_t; |
| typedef typename to_longest_alternative< |
| typename T::right_t>::plain_t b_t; |
| |
| typedef longest_alternative<a_t, b_t> result_t; |
| |
| typedef result_t plain_t; |
| typedef mpl::true_ choose_t; |
| }; |
| |
| template <typename A, typename B> |
| inline typename to_longest_alternative<alternative<A, B> >::result_t |
| to_longest_convert(alternative<A, B> const& alt, mpl::true_) |
| { |
| typedef typename to_longest_alternative< |
| alternative<A, B> >::result_t result_t; |
| return result_t( |
| to_longest_alternative<A>::convert(alt.left()), |
| to_longest_alternative<B>::convert(alt.right())); |
| } |
| |
| template <typename T> |
| inline typename to_longest_alternative<T>::result_t |
| to_longest_alternative<T>::convert(T const& a) |
| { |
| return to_longest_convert( |
| a, to_longest_alternative<T>::choose_t()); |
| } |
| |
| template <typename T> |
| struct select_to_longest |
| { |
| typedef typename mpl::if_< |
| is_alternative<T> // IF |
| , to_longest_recursive<T> // THEN |
| , to_longest_generic<T> // ELSE |
| >::type type; |
| |
| typedef typename select_to_longest::type::result_t result_t; |
| typedef typename select_to_longest::type::plain_t plain_t; |
| typedef typename select_to_longest::type::choose_t choose_t; |
| }; |
| |
| template <typename T> struct select_to_shortest; |
| |
| template <typename T> |
| struct to_shortest_alternative |
| { |
| typedef typename select_to_shortest<T>::result_t result_t; |
| typedef typename select_to_shortest<T>::plain_t plain_t; |
| typedef typename select_to_shortest<T>::choose_t choose_t; |
| static result_t convert(T const& a); |
| }; |
| |
| template <typename T> |
| struct to_shortest_generic |
| { |
| typedef T const& result_t; |
| typedef T plain_t; |
| typedef mpl::false_ choose_t; |
| }; |
| |
| template <typename T> |
| inline T const& |
| to_shortest_convert(T const& a, mpl::false_) { return a; } |
| |
| template <typename T> |
| struct to_shortest_recursive |
| { |
| typedef typename to_shortest_alternative< |
| typename T::left_t>::plain_t a_t; |
| typedef typename to_shortest_alternative< |
| typename T::right_t>::plain_t b_t; |
| |
| typedef shortest_alternative<a_t, b_t> result_t; |
| |
| typedef result_t plain_t; |
| typedef mpl::true_ choose_t; |
| }; |
| |
| template <typename A, typename B> |
| inline typename to_shortest_alternative<alternative<A, B> >::result_t |
| to_shortest_convert(alternative<A, B> const& alt, mpl::true_) |
| { |
| typedef typename to_shortest_alternative< |
| alternative<A, B> >::result_t result_t; |
| return result_t( |
| to_shortest_alternative<A>::convert(alt.left()), |
| to_shortest_alternative<B>::convert(alt.right())); |
| } |
| |
| template <typename T> |
| inline typename to_shortest_alternative<T>::result_t |
| to_shortest_alternative<T>::convert(T const& a) |
| { |
| return to_shortest_convert( |
| a, to_shortest_alternative<T>::choose_t()); |
| } |
| |
| template <typename T> |
| struct select_to_shortest |
| { |
| typedef typename mpl::if_< |
| is_alternative<T> // IF |
| , to_shortest_recursive<T> // THEN |
| , to_shortest_generic<T> // ELSE |
| >::type type; |
| |
| typedef typename select_to_shortest::type::result_t result_t; |
| typedef typename select_to_shortest::type::plain_t plain_t; |
| typedef typename select_to_shortest::type::choose_t choose_t; |
| }; |
| #else |
| template <typename T> |
| struct to_longest_alternative |
| { |
| typedef T result_t; |
| static result_t const& |
| convert(T const& a) // Special (end) case |
| { return a; } |
| }; |
| |
| template <typename A, typename B> |
| struct to_longest_alternative<alternative<A, B> > |
| { |
| typedef typename to_longest_alternative<A>::result_t a_t; |
| typedef typename to_longest_alternative<B>::result_t b_t; |
| typedef longest_alternative<a_t, b_t> result_t; |
| |
| static result_t |
| convert(alternative<A, B> const& alt) // Recursive case |
| { |
| return result_t( |
| to_longest_alternative<A>::convert(alt.left()), |
| to_longest_alternative<B>::convert(alt.right())); |
| } |
| }; |
| |
| template <typename T> |
| struct to_shortest_alternative |
| { |
| typedef T result_t; |
| static result_t const& |
| convert(T const& a) // Special (end) case |
| { return a; } |
| }; |
| |
| template <typename A, typename B> |
| struct to_shortest_alternative<alternative<A, B> > |
| { |
| typedef typename to_shortest_alternative<A>::result_t a_t; |
| typedef typename to_shortest_alternative<B>::result_t b_t; |
| typedef shortest_alternative<a_t, b_t> result_t; |
| |
| static result_t |
| convert(alternative<A, B> const& alt) // Recursive case |
| { |
| return result_t( |
| to_shortest_alternative<A>::convert(alt.left()), |
| to_shortest_alternative<B>::convert(alt.right())); |
| } |
| }; |
| #endif |
| } |
| |
| BOOST_SPIRIT_CLASSIC_NAMESPACE_END |
| |
| }} // namespace boost::spirit |
| |
| #endif |
| |