1 /*============================================================================= 2 Copyright (c) 1998-2003 Joel de Guzman 3 Copyright (c) 2001 Daniel Nuffer 4 Copyright (c) 2002 Hartmut Kaiser 5 http://spirit.sourceforge.net/ 6 7 Distributed under the Boost Software License, Version 1.0. (See accompanying 8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 =============================================================================*/ 10 #if !defined(BOOST_SPIRIT_EXCLUSIVE_OR_HPP) 11 #define BOOST_SPIRIT_EXCLUSIVE_OR_HPP 12 13 #include <boost/spirit/home/classic/namespace.hpp> 14 #include <boost/spirit/home/classic/core/parser.hpp> 15 #include <boost/spirit/home/classic/core/primitives/primitives.hpp> 16 #include <boost/spirit/home/classic/core/composite/composite.hpp> 17 #include <boost/spirit/home/classic/meta/as_parser.hpp> 18 19 namespace boost { namespace spirit { 20 21 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 22 23 /////////////////////////////////////////////////////////////////////////// 24 // 25 // exclusive_or class 26 // 27 // Handles expressions of the form: 28 // 29 // a ^ b 30 // 31 // where a and b are parsers. The expression returns a composite 32 // parser that matches a or b but not both. One (not both) of the 33 // operands may be a literal char, wchar_t or a primitive string 34 // char const*, wchar_t const*. 35 // 36 /////////////////////////////////////////////////////////////////////////// 37 struct exclusive_or_parser_gen; 38 39 template <typename A, typename B> 40 struct exclusive_or 41 : public binary<A, B, parser<exclusive_or<A, B> > > 42 { 43 typedef exclusive_or<A, B> self_t; 44 typedef binary_parser_category parser_category_t; 45 typedef exclusive_or_parser_gen parser_generator_t; 46 typedef binary<A, B, parser<self_t> > base_t; 47 exclusive_orboost::spirit::exclusive_or48 exclusive_or(A const& a, B const& b) 49 : base_t(a, b) {} 50 51 template <typename ScannerT> 52 typename parser_result<self_t, ScannerT>::type parseboost::spirit::exclusive_or53 parse(ScannerT const& scan) const 54 { 55 typedef typename parser_result<self_t, ScannerT>::type result_t; 56 typedef typename ScannerT::iterator_t iterator_t; 57 58 iterator_t save = scan.first; 59 result_t l = this->left().parse(scan); 60 std::swap(save, scan.first); 61 result_t r = this->right().parse(scan); 62 63 if (l ? !bool(r) : bool(r)) 64 { 65 if (l) 66 scan.first = save; 67 return l ? l : r; 68 } 69 70 return scan.no_match(); 71 } 72 }; 73 74 struct exclusive_or_parser_gen 75 { 76 template <typename A, typename B> 77 struct result 78 { 79 typedef 80 exclusive_or< 81 typename as_parser<A>::type 82 , typename as_parser<B>::type 83 > 84 type; 85 }; 86 87 template <typename A, typename B> 88 static exclusive_or< 89 typename as_parser<A>::type 90 , typename as_parser<B>::type 91 > generateboost::spirit::exclusive_or_parser_gen92 generate(A const& a, B const& b) 93 { 94 return exclusive_or<BOOST_DEDUCED_TYPENAME as_parser<A>::type, 95 BOOST_DEDUCED_TYPENAME as_parser<B>::type> 96 (as_parser<A>::convert(a), as_parser<B>::convert(b)); 97 } 98 }; 99 100 template <typename A, typename B> 101 exclusive_or<A, B> 102 operator^(parser<A> const& a, parser<B> const& b); 103 104 template <typename A> 105 exclusive_or<A, chlit<char> > 106 operator^(parser<A> const& a, char b); 107 108 template <typename B> 109 exclusive_or<chlit<char>, B> 110 operator^(char a, parser<B> const& b); 111 112 template <typename A> 113 exclusive_or<A, strlit<char const*> > 114 operator^(parser<A> const& a, char const* b); 115 116 template <typename B> 117 exclusive_or<strlit<char const*>, B> 118 operator^(char const* a, parser<B> const& b); 119 120 template <typename A> 121 exclusive_or<A, chlit<wchar_t> > 122 operator^(parser<A> const& a, wchar_t b); 123 124 template <typename B> 125 exclusive_or<chlit<wchar_t>, B> 126 operator^(wchar_t a, parser<B> const& b); 127 128 template <typename A> 129 exclusive_or<A, strlit<wchar_t const*> > 130 operator^(parser<A> const& a, wchar_t const* b); 131 132 template <typename B> 133 exclusive_or<strlit<wchar_t const*>, B> 134 operator^(wchar_t const* a, parser<B> const& b); 135 136 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 137 138 }} // namespace BOOST_SPIRIT_CLASSIC_NS 139 140 #endif 141 142 #include <boost/spirit/home/classic/core/composite/impl/exclusive_or.ipp> 143