You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
104 lines
3.5 KiB
104 lines
3.5 KiB
/*============================================================================= |
|
Copyright (c) 2002-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) |
|
=============================================================================*/ |
|
#ifndef BOOST_SPIRIT_CONDITIONS_IPP |
|
#define BOOST_SPIRIT_CONDITIONS_IPP |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
#include <boost/spirit/home/classic/meta/parser_traits.hpp> |
|
#include <boost/spirit/home/classic/core/composite/epsilon.hpp> |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
namespace boost { namespace spirit { |
|
|
|
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN |
|
|
|
namespace impl { |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// condition evaluation |
|
// |
|
/////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////// |
|
// condition_parser_selector, decides which parser to use for a condition |
|
// If the template argument is a parser then that parser is used. |
|
// If the template argument is a functor then a condition parser using |
|
// the functor is chosen |
|
|
|
template <typename T> struct embed_t_accessor |
|
{ |
|
typedef typename T::embed_t type; |
|
}; |
|
|
|
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 |
|
template <> struct embed_t_accessor<int> |
|
{ |
|
typedef int type; |
|
}; |
|
#endif |
|
|
|
template <typename ConditionT> |
|
struct condition_parser_selector |
|
{ |
|
typedef |
|
typename mpl::if_< |
|
is_parser<ConditionT>, |
|
ConditionT, |
|
condition_parser<ConditionT> |
|
>::type |
|
type; |
|
|
|
typedef typename embed_t_accessor<type>::type embed_t; |
|
}; |
|
|
|
////////////////////////////////// |
|
// condition_evaluator, uses a parser to check wether a condition is met |
|
// takes a parser or a functor that can be evaluated in boolean context |
|
// as template parameter. |
|
|
|
// JDG 4-15-03 refactored |
|
template <typename ConditionT> |
|
struct condition_evaluator |
|
{ |
|
typedef condition_parser_selector<ConditionT> selector_t; |
|
typedef typename selector_t::type selected_t; |
|
typedef typename selector_t::embed_t cond_embed_t; |
|
|
|
typedef typename boost::call_traits<cond_embed_t>::param_type |
|
param_t; |
|
|
|
condition_evaluator(param_t s) : cond(s) {} |
|
|
|
///////////////////////////// |
|
// evaluate, checks wether condition is met |
|
// returns length of a match or a negative number for no-match |
|
template <typename ScannerT> |
|
std::ptrdiff_t |
|
evaluate(ScannerT const &scan) const |
|
{ |
|
typedef typename ScannerT::iterator_t iterator_t; |
|
typedef typename parser_result<selected_t, ScannerT>::type cres_t; |
|
iterator_t save(scan.first); |
|
cres_t result = cond.parse(scan); |
|
if (!result) // reset the position if evaluation |
|
scan.first = save; // fails. |
|
return result.length(); |
|
} |
|
|
|
cond_embed_t cond; |
|
}; |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
} // namespace impl |
|
|
|
BOOST_SPIRIT_CLASSIC_NAMESPACE_END |
|
|
|
}} // namespace boost::spirit |
|
|
|
#endif
|
|
|