/*============================================================================= | |
Copyright (c) 1998-2003 Joel de Guzman | |
Copyright (c) 2001 Daniel Nuffer | |
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_DIRECTIVES_HPP) | |
#define BOOST_SPIRIT_DIRECTIVES_HPP | |
/////////////////////////////////////////////////////////////////////////////// | |
#include <algorithm> | |
#include <boost/spirit/home/classic/namespace.hpp> | |
#include <boost/spirit/home/classic/core/parser.hpp> | |
#include <boost/spirit/home/classic/core/scanner/skipper.hpp> | |
#include <boost/spirit/home/classic/core/primitives/primitives.hpp> | |
#include <boost/spirit/home/classic/core/composite/composite.hpp> | |
#include <boost/spirit/home/classic/core/composite/impl/directives.ipp> | |
namespace boost { namespace spirit { | |
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// contiguous class | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
struct lexeme_parser_gen; | |
template <typename ParserT> | |
struct contiguous | |
: public unary<ParserT, parser<contiguous<ParserT> > > | |
{ | |
typedef contiguous<ParserT> self_t; | |
typedef unary_parser_category parser_category_t; | |
typedef lexeme_parser_gen parser_generator_t; | |
typedef unary<ParserT, parser<self_t> > base_t; | |
template <typename ScannerT> | |
struct result | |
{ | |
typedef typename parser_result<ParserT, ScannerT>::type type; | |
}; | |
contiguous(ParserT const& p) | |
: base_t(p) {} | |
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> | |
(this->subject(), scan, scan); | |
} | |
}; | |
struct lexeme_parser_gen | |
{ | |
template <typename ParserT> | |
struct result { | |
typedef contiguous<ParserT> type; | |
}; | |
template <typename ParserT> | |
static contiguous<ParserT> | |
generate(parser<ParserT> const& subject) | |
{ | |
return contiguous<ParserT>(subject.derived()); | |
} | |
template <typename ParserT> | |
contiguous<ParserT> | |
operator[](parser<ParserT> const& subject) const | |
{ | |
return contiguous<ParserT>(subject.derived()); | |
} | |
}; | |
////////////////////////////////// | |
const lexeme_parser_gen lexeme_d = lexeme_parser_gen(); | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// lexeme_scanner | |
// | |
// Given a Scanner, return the correct scanner type that | |
// the lexeme_d uses. Scanner is assumed to be a phrase | |
// level scanner (see skipper.hpp) | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename ScannerT> | |
struct lexeme_scanner | |
{ | |
typedef scanner_policies< | |
no_skipper_iteration_policy< | |
typename ScannerT::iteration_policy_t>, | |
typename ScannerT::match_policy_t, | |
typename ScannerT::action_policy_t | |
> policies_t; | |
typedef typename | |
rebind_scanner_policies<ScannerT, policies_t>::type type; | |
}; | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// inhibit_case_iteration_policy class | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename BaseT> | |
struct inhibit_case_iteration_policy : public BaseT | |
{ | |
typedef BaseT base_t; | |
inhibit_case_iteration_policy() | |
: BaseT() {} | |
template <typename PolicyT> | |
inhibit_case_iteration_policy(PolicyT const& other) | |
: BaseT(other) {} | |
template <typename CharT> | |
CharT filter(CharT ch) const | |
{ return impl::tolower_(ch); } | |
}; | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// inhibit_case class | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
struct inhibit_case_parser_gen; | |
template <typename ParserT> | |
struct inhibit_case | |
: public unary<ParserT, parser<inhibit_case<ParserT> > > | |
{ | |
typedef inhibit_case<ParserT> self_t; | |
typedef unary_parser_category parser_category_t; | |
typedef inhibit_case_parser_gen parser_generator_t; | |
typedef unary<ParserT, parser<self_t> > base_t; | |
template <typename ScannerT> | |
struct result | |
{ | |
typedef typename parser_result<ParserT, ScannerT>::type type; | |
}; | |
inhibit_case(ParserT const& p) | |
: base_t(p) {} | |
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::inhibit_case_parser_parse<result_t> | |
(this->subject(), scan, scan); | |
} | |
}; | |
template <int N> | |
struct inhibit_case_parser_gen_base | |
{ | |
// This hack is needed to make borland happy. | |
// If these member operators were defined in the | |
// inhibit_case_parser_gen class, or if this class | |
// is non-templated, borland ICEs. | |
static inhibit_case<strlit<char const*> > | |
generate(char const* str) | |
{ return inhibit_case<strlit<char const*> >(str); } | |
static inhibit_case<strlit<wchar_t const*> > | |
generate(wchar_t const* str) | |
{ return inhibit_case<strlit<wchar_t const*> >(str); } | |
static inhibit_case<chlit<char> > | |
generate(char ch) | |
{ return inhibit_case<chlit<char> >(ch); } | |
static inhibit_case<chlit<wchar_t> > | |
generate(wchar_t ch) | |
{ return inhibit_case<chlit<wchar_t> >(ch); } | |
template <typename ParserT> | |
static inhibit_case<ParserT> | |
generate(parser<ParserT> const& subject) | |
{ return inhibit_case<ParserT>(subject.derived()); } | |
inhibit_case<strlit<char const*> > | |
operator[](char const* str) const | |
{ return inhibit_case<strlit<char const*> >(str); } | |
inhibit_case<strlit<wchar_t const*> > | |
operator[](wchar_t const* str) const | |
{ return inhibit_case<strlit<wchar_t const*> >(str); } | |
inhibit_case<chlit<char> > | |
operator[](char ch) const | |
{ return inhibit_case<chlit<char> >(ch); } | |
inhibit_case<chlit<wchar_t> > | |
operator[](wchar_t ch) const | |
{ return inhibit_case<chlit<wchar_t> >(ch); } | |
template <typename ParserT> | |
inhibit_case<ParserT> | |
operator[](parser<ParserT> const& subject) const | |
{ return inhibit_case<ParserT>(subject.derived()); } | |
}; | |
////////////////////////////////// | |
struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0> | |
{ | |
inhibit_case_parser_gen() {} | |
}; | |
////////////////////////////////// | |
// Depracated | |
const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen(); | |
// Preferred syntax | |
const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen(); | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// as_lower_scanner | |
// | |
// Given a Scanner, return the correct scanner type that | |
// the as_lower_d uses. Scanner is assumed to be a scanner | |
// with an inhibit_case_iteration_policy. | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename ScannerT> | |
struct as_lower_scanner | |
{ | |
typedef scanner_policies< | |
inhibit_case_iteration_policy< | |
typename ScannerT::iteration_policy_t>, | |
typename ScannerT::match_policy_t, | |
typename ScannerT::action_policy_t | |
> policies_t; | |
typedef typename | |
rebind_scanner_policies<ScannerT, policies_t>::type type; | |
}; | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// longest_alternative class | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
struct longest_parser_gen; | |
template <typename A, typename B> | |
struct longest_alternative | |
: public binary<A, B, parser<longest_alternative<A, B> > > | |
{ | |
typedef longest_alternative<A, B> self_t; | |
typedef binary_parser_category parser_category_t; | |
typedef longest_parser_gen parser_generator_t; | |
typedef binary<A, B, parser<self_t> > base_t; | |
longest_alternative(A const& a, B const& b) | |
: base_t(a, b) {} | |
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; | |
typename ScannerT::iterator_t save = scan.first; | |
result_t l = this->left().parse(scan); | |
std::swap(scan.first, save); | |
result_t r = this->right().parse(scan); | |
if (l || r) | |
{ | |
if (l.length() > r.length()) | |
{ | |
scan.first = save; | |
return l; | |
} | |
return r; | |
} | |
return scan.no_match(); | |
} | |
}; | |
struct longest_parser_gen | |
{ | |
template <typename A, typename B> | |
struct result { | |
typedef typename | |
impl::to_longest_alternative<alternative<A, B> >::result_t | |
type; | |
}; | |
template <typename A, typename B> | |
static typename | |
impl::to_longest_alternative<alternative<A, B> >::result_t | |
generate(alternative<A, B> const& alt) | |
{ | |
return impl::to_longest_alternative<alternative<A, B> >:: | |
convert(alt); | |
} | |
//'generate' for binary composite | |
template <typename A, typename B> | |
static | |
longest_alternative<A, B> | |
generate(A const &left, B const &right) | |
{ | |
return longest_alternative<A, B>(left, right); | |
} | |
template <typename A, typename B> | |
typename impl::to_longest_alternative<alternative<A, B> >::result_t | |
operator[](alternative<A, B> const& alt) const | |
{ | |
return impl::to_longest_alternative<alternative<A, B> >:: | |
convert(alt); | |
} | |
}; | |
const longest_parser_gen longest_d = longest_parser_gen(); | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// shortest_alternative class | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
struct shortest_parser_gen; | |
template <typename A, typename B> | |
struct shortest_alternative | |
: public binary<A, B, parser<shortest_alternative<A, B> > > | |
{ | |
typedef shortest_alternative<A, B> self_t; | |
typedef binary_parser_category parser_category_t; | |
typedef shortest_parser_gen parser_generator_t; | |
typedef binary<A, B, parser<self_t> > base_t; | |
shortest_alternative(A const& a, B const& b) | |
: base_t(a, b) {} | |
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; | |
typename ScannerT::iterator_t save = scan.first; | |
result_t l = this->left().parse(scan); | |
std::swap(scan.first, save); | |
result_t r = this->right().parse(scan); | |
if (l || r) | |
{ | |
if ((l.length() < r.length() && l) || !r) | |
{ | |
scan.first = save; | |
return l; | |
} | |
return r; | |
} | |
return scan.no_match(); | |
} | |
}; | |
struct shortest_parser_gen | |
{ | |
template <typename A, typename B> | |
struct result { | |
typedef typename | |
impl::to_shortest_alternative<alternative<A, B> >::result_t | |
type; | |
}; | |
template <typename A, typename B> | |
static typename | |
impl::to_shortest_alternative<alternative<A, B> >::result_t | |
generate(alternative<A, B> const& alt) | |
{ | |
return impl::to_shortest_alternative<alternative<A, B> >:: | |
convert(alt); | |
} | |
//'generate' for binary composite | |
template <typename A, typename B> | |
static | |
shortest_alternative<A, B> | |
generate(A const &left, B const &right) | |
{ | |
return shortest_alternative<A, B>(left, right); | |
} | |
template <typename A, typename B> | |
typename impl::to_shortest_alternative<alternative<A, B> >::result_t | |
operator[](alternative<A, B> const& alt) const | |
{ | |
return impl::to_shortest_alternative<alternative<A, B> >:: | |
convert(alt); | |
} | |
}; | |
const shortest_parser_gen shortest_d = shortest_parser_gen(); | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// min_bounded class | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename BoundsT> | |
struct min_bounded_gen; | |
template <typename ParserT, typename BoundsT> | |
struct min_bounded | |
: public unary<ParserT, parser<min_bounded<ParserT, BoundsT> > > | |
{ | |
typedef min_bounded<ParserT, BoundsT> self_t; | |
typedef unary_parser_category parser_category_t; | |
typedef min_bounded_gen<BoundsT> parser_generator_t; | |
typedef unary<ParserT, parser<self_t> > base_t; | |
template <typename ScannerT> | |
struct result | |
{ | |
typedef typename parser_result<ParserT, ScannerT>::type type; | |
}; | |
min_bounded(ParserT const& p, BoundsT const& min__) | |
: base_t(p) | |
, min_(min__) {} | |
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; | |
result_t hit = this->subject().parse(scan); | |
if (hit.has_valid_attribute() && hit.value() < min_) | |
return scan.no_match(); | |
return hit; | |
} | |
BoundsT min_; | |
}; | |
template <typename BoundsT> | |
struct min_bounded_gen | |
{ | |
min_bounded_gen(BoundsT const& min__) | |
: min_(min__) {} | |
template <typename DerivedT> | |
min_bounded<DerivedT, BoundsT> | |
operator[](parser<DerivedT> const& p) const | |
{ return min_bounded<DerivedT, BoundsT>(p.derived(), min_); } | |
BoundsT min_; | |
}; | |
template <typename BoundsT> | |
inline min_bounded_gen<BoundsT> | |
min_limit_d(BoundsT const& min_) | |
{ return min_bounded_gen<BoundsT>(min_); } | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// max_bounded class | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename BoundsT> | |
struct max_bounded_gen; | |
template <typename ParserT, typename BoundsT> | |
struct max_bounded | |
: public unary<ParserT, parser<max_bounded<ParserT, BoundsT> > > | |
{ | |
typedef max_bounded<ParserT, BoundsT> self_t; | |
typedef unary_parser_category parser_category_t; | |
typedef max_bounded_gen<BoundsT> parser_generator_t; | |
typedef unary<ParserT, parser<self_t> > base_t; | |
template <typename ScannerT> | |
struct result | |
{ | |
typedef typename parser_result<ParserT, ScannerT>::type type; | |
}; | |
max_bounded(ParserT const& p, BoundsT const& max__) | |
: base_t(p) | |
, max_(max__) {} | |
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; | |
result_t hit = this->subject().parse(scan); | |
if (hit.has_valid_attribute() && hit.value() > max_) | |
return scan.no_match(); | |
return hit; | |
} | |
BoundsT max_; | |
}; | |
template <typename BoundsT> | |
struct max_bounded_gen | |
{ | |
max_bounded_gen(BoundsT const& max__) | |
: max_(max__) {} | |
template <typename DerivedT> | |
max_bounded<DerivedT, BoundsT> | |
operator[](parser<DerivedT> const& p) const | |
{ return max_bounded<DerivedT, BoundsT>(p.derived(), max_); } | |
BoundsT max_; | |
}; | |
////////////////////////////////// | |
template <typename BoundsT> | |
inline max_bounded_gen<BoundsT> | |
max_limit_d(BoundsT const& max_) | |
{ return max_bounded_gen<BoundsT>(max_); } | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// bounded class | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename BoundsT> | |
struct bounded_gen; | |
template <typename ParserT, typename BoundsT> | |
struct bounded | |
: public unary<ParserT, parser<bounded<ParserT, BoundsT> > > | |
{ | |
typedef bounded<ParserT, BoundsT> self_t; | |
typedef unary_parser_category parser_category_t; | |
typedef bounded_gen<BoundsT> parser_generator_t; | |
typedef unary<ParserT, parser<self_t> > base_t; | |
template <typename ScannerT> | |
struct result | |
{ | |
typedef typename parser_result<ParserT, ScannerT>::type type; | |
}; | |
bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__) | |
: base_t(p) | |
, min_(min__) | |
, max_(max__) {} | |
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; | |
result_t hit = this->subject().parse(scan); | |
if (hit.has_valid_attribute() && | |
(hit.value() < min_ || hit.value() > max_)) | |
return scan.no_match(); | |
return hit; | |
} | |
BoundsT min_, max_; | |
}; | |
template <typename BoundsT> | |
struct bounded_gen | |
{ | |
bounded_gen(BoundsT const& min__, BoundsT const& max__) | |
: min_(min__) | |
, max_(max__) {} | |
template <typename DerivedT> | |
bounded<DerivedT, BoundsT> | |
operator[](parser<DerivedT> const& p) const | |
{ return bounded<DerivedT, BoundsT>(p.derived(), min_, max_); } | |
BoundsT min_, max_; | |
}; | |
template <typename BoundsT> | |
inline bounded_gen<BoundsT> | |
limit_d(BoundsT const& min_, BoundsT const& max_) | |
{ return bounded_gen<BoundsT>(min_, max_); } | |
BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
}} // namespace BOOST_SPIRIT_CLASSIC_NS | |
#endif | |