/*============================================================================= | |
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 parser_result<self_t, ScannerT>::type result_t; | |
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 |