]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Copyright (c) 2001-2011 Joel de Guzman | |
3 | Copyright (c) 2001-2011 Hartmut Kaiser | |
4 | ||
5 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
6 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | =============================================================================*/ | |
8 | #if !defined(SPIRIT_ALTERNATIVE_FEBRUARY_05_2007_1153AM) | |
9 | #define SPIRIT_ALTERNATIVE_FEBRUARY_05_2007_1153AM | |
10 | ||
11 | #if defined(_MSC_VER) | |
12 | #pragma once | |
13 | #endif | |
14 | ||
15 | #include <boost/spirit/home/qi/detail/alternative_function.hpp> | |
16 | #include <boost/spirit/home/qi/meta_compiler.hpp> | |
17 | #include <boost/spirit/home/qi/parser.hpp> | |
18 | #include <boost/spirit/home/qi/detail/attributes.hpp> | |
19 | #include <boost/spirit/home/support/has_semantic_action.hpp> | |
20 | #include <boost/spirit/home/support/handles_container.hpp> | |
21 | #include <boost/spirit/home/support/detail/what_function.hpp> | |
22 | #include <boost/spirit/home/support/unused.hpp> | |
23 | #include <boost/spirit/home/support/info.hpp> | |
24 | #include <boost/fusion/include/any.hpp> | |
25 | #include <boost/fusion/include/mpl.hpp> | |
26 | #include <boost/fusion/include/for_each.hpp> | |
27 | ||
28 | namespace boost { namespace spirit | |
29 | { | |
30 | /////////////////////////////////////////////////////////////////////////// | |
31 | // Enablers | |
32 | /////////////////////////////////////////////////////////////////////////// | |
33 | template <> | |
34 | struct use_operator<qi::domain, proto::tag::bitwise_or> // enables | | |
35 | : mpl::true_ {}; | |
36 | ||
37 | template <> | |
38 | struct flatten_tree<qi::domain, proto::tag::bitwise_or> // flattens | | |
39 | : mpl::true_ {}; | |
40 | }} | |
41 | ||
42 | namespace boost { namespace spirit { namespace qi | |
43 | { | |
44 | template <typename Elements> | |
45 | struct alternative : nary_parser<alternative<Elements> > | |
46 | { | |
47 | template <typename Context, typename Iterator> | |
48 | struct attribute | |
49 | { | |
50 | // Put all the element attributes in a tuple | |
51 | typedef typename traits::build_attribute_sequence< | |
52 | Elements, Context, traits::alternative_attribute_transform | |
53 | , Iterator, qi::domain | |
54 | >::type all_attributes; | |
55 | ||
56 | // Ok, now make a variant over the attribute sequence. Note that | |
57 | // build_variant makes sure that 1) all attributes in the variant | |
58 | // are unique 2) puts the unused attribute, if there is any, to | |
59 | // the front and 3) collapses single element variants, variant<T> | |
60 | // to T. | |
61 | typedef typename | |
62 | traits::build_variant<all_attributes>::type | |
63 | type; | |
64 | }; | |
65 | ||
66 | alternative(Elements const& elements_) | |
67 | : elements(elements_) {} | |
68 | ||
69 | template <typename Iterator, typename Context | |
70 | , typename Skipper, typename Attribute> | |
71 | bool parse(Iterator& first, Iterator const& last | |
72 | , Context& context, Skipper const& skipper | |
73 | , Attribute& attr_) const | |
74 | { | |
75 | detail::alternative_function<Iterator, Context, Skipper, Attribute> | |
76 | f(first, last, context, skipper, attr_); | |
77 | ||
78 | // return true if *any* of the parsers succeed | |
79 | return fusion::any(elements, f); | |
80 | } | |
81 | ||
82 | template <typename Context> | |
83 | info what(Context& context) const | |
84 | { | |
85 | info result("alternative"); | |
86 | fusion::for_each(elements, | |
87 | spirit::detail::what_function<Context>(result, context)); | |
88 | return result; | |
89 | } | |
90 | ||
91 | Elements elements; | |
92 | }; | |
93 | ||
94 | /////////////////////////////////////////////////////////////////////////// | |
95 | // Parser generators: make_xxx function (objects) | |
96 | /////////////////////////////////////////////////////////////////////////// | |
97 | template <typename Elements, typename Modifiers> | |
98 | struct make_composite<proto::tag::bitwise_or, Elements, Modifiers> | |
99 | : make_nary_composite<Elements, alternative> | |
100 | {}; | |
101 | }}} | |
102 | ||
103 | namespace boost { namespace spirit { namespace traits | |
104 | { | |
105 | /////////////////////////////////////////////////////////////////////////// | |
106 | template <typename Elements> | |
107 | struct has_semantic_action<qi::alternative<Elements> > | |
108 | : nary_has_semantic_action<Elements> {}; | |
109 | ||
110 | /////////////////////////////////////////////////////////////////////////// | |
111 | template <typename Elements, typename Attribute, typename Context | |
112 | , typename Iterator> | |
113 | struct handles_container<qi::alternative<Elements>, Attribute, Context | |
114 | , Iterator> | |
115 | : nary_handles_container<Elements, Attribute, Context, Iterator> {}; | |
116 | }}} | |
117 | ||
118 | #endif |