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_SEQUENTIAL_OR_HPP) 11 #define BOOST_SPIRIT_SEQUENTIAL_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 // sequential-or class 26 // 27 // Handles expressions of the form: 28 // 29 // a || b 30 // 31 // Equivalent to 32 // 33 // a | b | a >> b; 34 // 35 // where a and b are parsers. The expression returns a composite 36 // parser that matches matches a or b in sequence. One (not both) of 37 // the operands may be a literal char, wchar_t or a primitive string 38 // char const*, wchar_t const*. 39 // 40 /////////////////////////////////////////////////////////////////////////// 41 struct sequential_or_parser_gen; 42 43 template <typename A, typename B> 44 struct sequential_or : public binary<A, B, parser<sequential_or<A, B> > > 45 { 46 typedef sequential_or<A, B> self_t; 47 typedef binary_parser_category parser_category_t; 48 typedef sequential_or_parser_gen parser_generator_t; 49 typedef binary<A, B, parser<self_t> > base_t; 50 sequential_orboost::spirit::sequential_or51 sequential_or(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::sequential_or56 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 { // scope for save 61 iterator_t save = scan.first; 62 if (result_t ma = this->left().parse(scan)) 63 { 64 save = scan.first; 65 if (result_t mb = this->right().parse(scan)) 66 { 67 // matched a b 68 scan.concat_match(ma, mb); 69 return ma; 70 } 71 else 72 { 73 // matched a 74 scan.first = save; 75 return ma; 76 } 77 } 78 scan.first = save; 79 } 80 81 // matched b 82 return this->right().parse(scan); 83 } 84 }; 85 86 struct sequential_or_parser_gen 87 { 88 template <typename A, typename B> 89 struct result 90 { 91 typedef 92 sequential_or< 93 typename as_parser<A>::type 94 , typename as_parser<B>::type 95 > 96 type; 97 }; 98 99 template <typename A, typename B> 100 static sequential_or< 101 typename as_parser<A>::type 102 , typename as_parser<B>::type 103 > generateboost::spirit::sequential_or_parser_gen104 generate(A const& a, B const& b) 105 { 106 return sequential_or<BOOST_DEDUCED_TYPENAME as_parser<A>::type, 107 BOOST_DEDUCED_TYPENAME as_parser<B>::type> 108 (as_parser<A>::convert(a), as_parser<B>::convert(b)); 109 } 110 }; 111 112 template <typename A, typename B> 113 sequential_or<A, B> 114 operator||(parser<A> const& a, parser<B> const& b); 115 116 template <typename A> 117 sequential_or<A, chlit<char> > 118 operator||(parser<A> const& a, char b); 119 120 template <typename B> 121 sequential_or<chlit<char>, B> 122 operator||(char a, parser<B> const& b); 123 124 template <typename A> 125 sequential_or<A, strlit<char const*> > 126 operator||(parser<A> const& a, char const* b); 127 128 template <typename B> 129 sequential_or<strlit<char const*>, B> 130 operator||(char const* a, parser<B> const& b); 131 132 template <typename A> 133 sequential_or<A, chlit<wchar_t> > 134 operator||(parser<A> const& a, wchar_t b); 135 136 template <typename B> 137 sequential_or<chlit<wchar_t>, B> 138 operator||(wchar_t a, parser<B> const& b); 139 140 template <typename A> 141 sequential_or<A, strlit<wchar_t const*> > 142 operator||(parser<A> const& a, wchar_t const* b); 143 144 template <typename B> 145 sequential_or<strlit<wchar_t const*>, B> 146 operator||(wchar_t const* a, parser<B> const& b); 147 148 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 149 150 }} // namespace BOOST_SPIRIT_CLASSIC_NS 151 152 #endif 153 154 #include <boost/spirit/home/classic/core/composite/impl/sequential_or.ipp> 155