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_ALTERNATIVE_HPP)
11 #define BOOST_SPIRIT_ALTERNATIVE_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 ///////////////////////////////////////////////////////////////////////////
27 // Handles expressions of the form:
31 // where a and b are parsers. The expression returns a composite
32 // parser that matches a or b. One (not both) of the operands may
33 // be a literal char, wchar_t or a primitive string char const*,
36 // The expression is short circuit evaluated. b is never touched
37 // when a is returns a successful match.
39 ///////////////////////////////////////////////////////////////////////////
40 struct alternative_parser_gen;
42 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
44 #pragma warning(disable:4512) //assignment operator could not be generated
47 template <typename A, typename B>
49 : public binary<A, B, parser<alternative<A, B> > >
51 typedef alternative<A, B> self_t;
52 typedef binary_parser_category parser_category_t;
53 typedef alternative_parser_gen parser_generator_t;
54 typedef binary<A, B, parser<self_t> > base_t;
56 alternative(A const& a, B const& b)
59 template <typename ScannerT>
60 typename parser_result<self_t, ScannerT>::type
61 parse(ScannerT const& scan) const
63 typedef typename parser_result<self_t, ScannerT>::type result_t;
64 typedef typename ScannerT::iterator_t iterator_t;
66 iterator_t save = scan.first;
67 if (result_t hit = this->left().parse(scan))
71 return this->right().parse(scan);
75 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
79 struct alternative_parser_gen
81 template <typename A, typename B>
86 typename as_parser<A>::type
87 , typename as_parser<B>::type
92 template <typename A, typename B>
94 typename as_parser<A>::type
95 , typename as_parser<B>::type
97 generate(A const& a, B const& b)
99 return alternative<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
100 BOOST_DEDUCED_TYPENAME as_parser<B>::type>
101 (as_parser<A>::convert(a), as_parser<B>::convert(b));
105 template <typename A, typename B>
107 operator|(parser<A> const& a, parser<B> const& b);
109 template <typename A>
110 alternative<A, chlit<char> >
111 operator|(parser<A> const& a, char b);
113 template <typename B>
114 alternative<chlit<char>, B>
115 operator|(char a, parser<B> const& b);
117 template <typename A>
118 alternative<A, strlit<char const*> >
119 operator|(parser<A> const& a, char const* b);
121 template <typename B>
122 alternative<strlit<char const*>, B>
123 operator|(char const* a, parser<B> const& b);
125 template <typename A>
126 alternative<A, chlit<wchar_t> >
127 operator|(parser<A> const& a, wchar_t b);
129 template <typename B>
130 alternative<chlit<wchar_t>, B>
131 operator|(wchar_t a, parser<B> const& b);
133 template <typename A>
134 alternative<A, strlit<wchar_t const*> >
135 operator|(parser<A> const& a, wchar_t const* b);
137 template <typename B>
138 alternative<strlit<wchar_t const*>, B>
139 operator|(wchar_t const* a, parser<B> const& b);
141 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
143 }} // namespace BOOST_SPIRIT_CLASSIC_NS
147 #include <boost/spirit/home/classic/core/composite/impl/alternative.ipp>