• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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