| /*============================================================================= |
| 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 |