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_INTERSECTION_HPP) 11 #define BOOST_SPIRIT_INTERSECTION_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 // intersection 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 and b. One (not both) of the operands may 33 // be a literal char, wchar_t or a primitive string char const*, 34 // wchar_t const*. 35 // 36 // The expression is short circuit evaluated. b is never touched 37 // when a is returns a no-match. 38 // 39 /////////////////////////////////////////////////////////////////////////// 40 struct intersection_parser_gen; 41 42 template <typename A, typename B> 43 struct intersection 44 : public binary<A, B, parser<intersection<A, B> > > 45 { 46 typedef intersection<A, B> self_t; 47 typedef binary_parser_category parser_category_t; 48 typedef intersection_parser_gen parser_generator_t; 49 typedef binary<A, B, parser<self_t> > base_t; 50 intersectionboost::spirit::intersection51 intersection(A const& a, B const& b) 52 : base_t(a, b) {} 53 54 template <typename ScannerT> 55 typename parser_result<self_t, ScannerT>::type parseboost::spirit::intersection56 parse(ScannerT const& scan) const 57 { 58 typedef typename parser_result<self_t, ScannerT>::type result_t; 59 typedef typename ScannerT::iterator_t iterator_t; 60 iterator_t save = scan.first; 61 if (result_t hl = this->left().parse(scan)) 62 { 63 ScannerT bscan(scan.first, scan.first, scan); 64 scan.first = save; 65 result_t hr = this->right().parse(bscan); 66 if (hl.length() == hr.length()) 67 return hl; 68 } 69 70 return scan.no_match(); 71 } 72 }; 73 74 struct intersection_parser_gen 75 { 76 template <typename A, typename B> 77 struct result 78 { 79 typedef 80 intersection< 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 intersection< 89 typename as_parser<A>::type 90 , typename as_parser<B>::type 91 > generateboost::spirit::intersection_parser_gen92 generate(A const& a, B const& b) 93 { 94 return intersection<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 intersection<A, B> 102 operator&(parser<A> const& a, parser<B> const& b); 103 104 template <typename A> 105 intersection<A, chlit<char> > 106 operator&(parser<A> const& a, char b); 107 108 template <typename B> 109 intersection<chlit<char>, B> 110 operator&(char a, parser<B> const& b); 111 112 template <typename A> 113 intersection<A, strlit<char const*> > 114 operator&(parser<A> const& a, char const* b); 115 116 template <typename B> 117 intersection<strlit<char const*>, B> 118 operator&(char const* a, parser<B> const& b); 119 120 template <typename A> 121 intersection<A, chlit<wchar_t> > 122 operator&(parser<A> const& a, wchar_t b); 123 124 template <typename B> 125 intersection<chlit<wchar_t>, B> 126 operator&(wchar_t a, parser<B> const& b); 127 128 template <typename A> 129 intersection<A, strlit<wchar_t const*> > 130 operator&(parser<A> const& a, wchar_t const* b); 131 132 template <typename B> 133 intersection<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/intersection.ipp> 143