Line data Source code
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_ALTERNATIVE_HPP)
11 : #define BOOST_SPIRIT_ALTERNATIVE_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 : // alternative 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 or 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 successful match.
38 : //
39 : ///////////////////////////////////////////////////////////////////////////
40 : struct alternative_parser_gen;
41 :
42 : #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
43 : #pragma warning(push)
44 : #pragma warning(disable:4512) //assignment operator could not be generated
45 : #endif
46 :
47 : template <typename A, typename B>
48 : struct alternative
49 : : public binary<A, B, parser<alternative<A, B> > >
50 : {
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;
55 :
56 0 : alternative(A const& a, B const& b)
57 0 : : base_t(a, b) {}
58 :
59 : template <typename ScannerT>
60 : typename parser_result<self_t, ScannerT>::type
61 0 : parse(ScannerT const& scan) const
62 : {
63 : typedef typename parser_result<self_t, ScannerT>::type result_t;
64 : typedef typename ScannerT::iterator_t iterator_t;
65 : { // scope for save
66 0 : iterator_t save = scan.first;
67 0 : if (result_t hit = this->left().parse(scan))
68 0 : return hit;
69 0 : scan.first = save;
70 : }
71 0 : return this->right().parse(scan);
72 : }
73 : };
74 :
75 : #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
76 : #pragma warning(pop)
77 : #endif
78 :
79 : struct alternative_parser_gen
80 : {
81 : template <typename A, typename B>
82 : struct result
83 : {
84 : typedef
85 : alternative<
86 : typename as_parser<A>::type
87 : , typename as_parser<B>::type
88 : >
89 : type;
90 : };
91 :
92 : template <typename A, typename B>
93 : static alternative<
94 : typename as_parser<A>::type
95 : , typename as_parser<B>::type
96 : >
97 : generate(A const& a, B const& b)
98 : {
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));
102 : }
103 : };
104 :
105 : template <typename A, typename B>
106 : alternative<A, B>
107 : operator|(parser<A> const& a, parser<B> const& b);
108 :
109 : template <typename A>
110 : alternative<A, chlit<char> >
111 : operator|(parser<A> const& a, char b);
112 :
113 : template <typename B>
114 : alternative<chlit<char>, B>
115 : operator|(char a, parser<B> const& b);
116 :
117 : template <typename A>
118 : alternative<A, strlit<char const*> >
119 : operator|(parser<A> const& a, char const* b);
120 :
121 : template <typename B>
122 : alternative<strlit<char const*>, B>
123 : operator|(char const* a, parser<B> const& b);
124 :
125 : template <typename A>
126 : alternative<A, chlit<wchar_t> >
127 : operator|(parser<A> const& a, wchar_t b);
128 :
129 : template <typename B>
130 : alternative<chlit<wchar_t>, B>
131 : operator|(wchar_t a, parser<B> const& b);
132 :
133 : template <typename A>
134 : alternative<A, strlit<wchar_t const*> >
135 : operator|(parser<A> const& a, wchar_t const* b);
136 :
137 : template <typename B>
138 : alternative<strlit<wchar_t const*>, B>
139 : operator|(wchar_t const* a, parser<B> const& b);
140 :
141 : BOOST_SPIRIT_CLASSIC_NAMESPACE_END
142 :
143 : }} // namespace BOOST_SPIRIT_CLASSIC_NS
144 :
145 : #endif
146 :
147 : #include <boost/spirit/home/classic/core/composite/impl/alternative.ipp>
|