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_DIFFERENCE_HPP) 11 #define BOOST_SPIRIT_DIFFERENCE_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 // difference: a - b; Matches a but not b 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 but not b. One (not both) of the operands 33 // may be a literal char, wchar_t or a primitive string char const*, 34 // wchar_t const*. 35 // 36 /////////////////////////////////////////////////////////////////////////// 37 struct difference_parser_gen; 38 39 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 40 #pragma warning(push) 41 #pragma warning(disable:4512) //assignment operator could not be generated 42 #endif 43 44 template <typename A, typename B> 45 struct difference 46 : public binary<A, B, parser<difference<A, B> > > 47 { 48 typedef difference<A, B> self_t; 49 typedef binary_parser_category parser_category_t; 50 typedef difference_parser_gen parser_generator_t; 51 typedef binary<A, B, parser<self_t> > base_t; 52 differenceboost::spirit::difference53 difference(A const& a, B const& b) 54 : base_t(a, b) {} 55 56 template <typename ScannerT> 57 typename parser_result<self_t, ScannerT>::type parseboost::spirit::difference58 parse(ScannerT const& scan) const 59 { 60 typedef typename parser_result<self_t, ScannerT>::type result_t; 61 typedef typename ScannerT::iterator_t iterator_t; 62 iterator_t save = scan.first; 63 if (result_t hl = this->left().parse(scan)) 64 { 65 std::swap(save, scan.first); 66 result_t hr = this->right().parse(scan); 67 if (!hr || (hr.length() < hl.length())) 68 { 69 scan.first = save; 70 return hl; 71 } 72 } 73 74 return scan.no_match(); 75 } 76 }; 77 78 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 79 #pragma warning(pop) 80 #endif 81 82 struct difference_parser_gen 83 { 84 template <typename A, typename B> 85 struct result 86 { 87 typedef 88 difference< 89 typename as_parser<A>::type 90 , typename as_parser<B>::type 91 > 92 type; 93 }; 94 95 template <typename A, typename B> 96 static difference< 97 typename as_parser<A>::type 98 , typename as_parser<B>::type 99 > generateboost::spirit::difference_parser_gen100 generate(A const& a, B const& b) 101 { 102 return difference<BOOST_DEDUCED_TYPENAME as_parser<A>::type, 103 BOOST_DEDUCED_TYPENAME as_parser<B>::type> 104 (as_parser<A>::convert(a), as_parser<B>::convert(b)); 105 } 106 }; 107 108 template <typename A, typename B> 109 difference<A, B> 110 operator-(parser<A> const& a, parser<B> const& b); 111 112 template <typename A> 113 difference<A, chlit<char> > 114 operator-(parser<A> const& a, char b); 115 116 template <typename B> 117 difference<chlit<char>, B> 118 operator-(char a, parser<B> const& b); 119 120 template <typename A> 121 difference<A, strlit<char const*> > 122 operator-(parser<A> const& a, char const* b); 123 124 template <typename B> 125 difference<strlit<char const*>, B> 126 operator-(char const* a, parser<B> const& b); 127 128 template <typename A> 129 difference<A, chlit<wchar_t> > 130 operator-(parser<A> const& a, wchar_t b); 131 132 template <typename B> 133 difference<chlit<wchar_t>, B> 134 operator-(wchar_t a, parser<B> const& b); 135 136 template <typename A> 137 difference<A, strlit<wchar_t const*> > 138 operator-(parser<A> const& a, wchar_t const* b); 139 140 template <typename B> 141 difference<strlit<wchar_t const*>, B> 142 operator-(wchar_t const* a, parser<B> const& b); 143 144 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 145 146 }} // namespace BOOST_SPIRIT_CLASSIC_NS 147 148 #endif 149 150 #include <boost/spirit/home/classic/core/composite/impl/difference.ipp> 151