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/
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
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>
19 namespace boost { namespace spirit {
21 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
23 ///////////////////////////////////////////////////////////////////////////
25 // sequential-or class
27 // Handles expressions of the form:
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*.
40 ///////////////////////////////////////////////////////////////////////////
41 struct sequential_or_parser_gen;
43 template <typename A, typename B>
44 struct sequential_or : public binary<A, B, parser<sequential_or<A, B> > >
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;
51 sequential_or(A const& a, B const& b)
54 template <typename ScannerT>
55 typename parser_result<self_t, ScannerT>::type
56 parse(ScannerT const& scan) const
58 typedef typename parser_result<self_t, ScannerT>::type result_t;
59 typedef typename ScannerT::iterator_t iterator_t;
61 iterator_t save = scan.first;
62 if (result_t ma = this->left().parse(scan))
65 if (result_t mb = this->right().parse(scan))
68 scan.concat_match(ma, mb);
82 return this->right().parse(scan);
86 struct sequential_or_parser_gen
88 template <typename A, typename B>
93 typename as_parser<A>::type
94 , typename as_parser<B>::type
99 template <typename A, typename B>
100 static sequential_or<
101 typename as_parser<A>::type
102 , typename as_parser<B>::type
104 generate(A const& a, B const& b)
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));
112 template <typename A, typename B>
114 operator||(parser<A> const& a, parser<B> const& b);
116 template <typename A>
117 sequential_or<A, chlit<char> >
118 operator||(parser<A> const& a, char b);
120 template <typename B>
121 sequential_or<chlit<char>, B>
122 operator||(char a, parser<B> const& b);
124 template <typename A>
125 sequential_or<A, strlit<char const*> >
126 operator||(parser<A> const& a, char const* b);
128 template <typename B>
129 sequential_or<strlit<char const*>, B>
130 operator||(char const* a, parser<B> const& b);
132 template <typename A>
133 sequential_or<A, chlit<wchar_t> >
134 operator||(parser<A> const& a, wchar_t b);
136 template <typename B>
137 sequential_or<chlit<wchar_t>, B>
138 operator||(wchar_t a, parser<B> const& b);
140 template <typename A>
141 sequential_or<A, strlit<wchar_t const*> >
142 operator||(parser<A> const& a, wchar_t const* b);
144 template <typename B>
145 sequential_or<strlit<wchar_t const*>, B>
146 operator||(wchar_t const* a, parser<B> const& b);
148 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
150 }} // namespace BOOST_SPIRIT_CLASSIC_NS
154 #include <boost/spirit/home/classic/core/composite/impl/sequential_or.ipp>