Chris@102
|
1 /*=============================================================================
|
Chris@102
|
2 Copyright (c) 2001-2014 Joel de Guzman
|
Chris@102
|
3
|
Chris@102
|
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@102
|
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
6 ==============================================================================*/
|
Chris@102
|
7 #if !defined(BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM)
|
Chris@102
|
8 #define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM
|
Chris@102
|
9
|
Chris@102
|
10 #if defined(_MSC_VER)
|
Chris@102
|
11 #pragma once
|
Chris@102
|
12 #endif
|
Chris@102
|
13
|
Chris@102
|
14 #include <boost/spirit/home/x3/nonterminal/detail/rule.hpp>
|
Chris@102
|
15 #include <boost/type_traits/is_same.hpp>
|
Chris@102
|
16 #include <boost/spirit/home/x3/support/context.hpp>
|
Chris@102
|
17 #include <boost/preprocessor/variadic/to_seq.hpp>
|
Chris@102
|
18 #include <boost/preprocessor/variadic/elem.hpp>
|
Chris@102
|
19 #include <boost/preprocessor/seq/for_each.hpp>
|
Chris@102
|
20
|
Chris@102
|
21 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
|
Chris@102
|
22 #include <typeinfo>
|
Chris@102
|
23 #endif
|
Chris@102
|
24
|
Chris@102
|
25 namespace boost { namespace spirit { namespace x3
|
Chris@102
|
26 {
|
Chris@102
|
27 template <typename ID>
|
Chris@102
|
28 struct identity {};
|
Chris@102
|
29
|
Chris@102
|
30 // default parse_rule implementation
|
Chris@102
|
31 template <typename ID, typename Attribute, typename Iterator
|
Chris@102
|
32 , typename Context, typename ActualAttribute>
|
Chris@102
|
33 inline detail::default_parse_rule_result
|
Chris@102
|
34 parse_rule(
|
Chris@102
|
35 rule<ID, Attribute> rule_
|
Chris@102
|
36 , Iterator& first, Iterator const& last
|
Chris@102
|
37 , Context const& context, ActualAttribute& attr)
|
Chris@102
|
38 {
|
Chris@102
|
39 static_assert(!is_same<decltype(get<ID>(context)), unused_type>::value,
|
Chris@102
|
40 "BOOST_SPIRIT_DEFINE undefined for this rule.");
|
Chris@102
|
41 return get<ID>(context).parse(first, last, context, unused, attr);
|
Chris@102
|
42 }
|
Chris@102
|
43
|
Chris@102
|
44 template <typename ID, typename RHS, typename Attribute, bool force_attribute_>
|
Chris@102
|
45 struct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_>>
|
Chris@102
|
46 {
|
Chris@102
|
47 typedef rule_definition<ID, RHS, Attribute, force_attribute_> this_type;
|
Chris@102
|
48 typedef ID id;
|
Chris@102
|
49 typedef RHS rhs_type;
|
Chris@102
|
50 typedef rule<ID, Attribute> lhs_type;
|
Chris@102
|
51 typedef Attribute attribute_type;
|
Chris@102
|
52
|
Chris@102
|
53 static bool const has_attribute =
|
Chris@102
|
54 !is_same<Attribute, unused_type>::value;
|
Chris@102
|
55 static bool const handles_container =
|
Chris@102
|
56 traits::is_container<Attribute>::value;
|
Chris@102
|
57 static bool const force_attribute =
|
Chris@102
|
58 force_attribute_;
|
Chris@102
|
59
|
Chris@102
|
60 rule_definition(RHS rhs, char const* name)
|
Chris@102
|
61 : rhs(rhs), name(name) {}
|
Chris@102
|
62
|
Chris@102
|
63 template <typename Iterator, typename Context, typename Attribute_>
|
Chris@102
|
64 bool parse(Iterator& first, Iterator const& last
|
Chris@102
|
65 , Context const& context, unused_type, Attribute_& attr) const
|
Chris@102
|
66 {
|
Chris@102
|
67 return detail::rule_parser<attribute_type, ID>
|
Chris@102
|
68 ::call_rule_definition(
|
Chris@102
|
69 rhs, name, first, last
|
Chris@102
|
70 , context
|
Chris@102
|
71 , attr
|
Chris@102
|
72 , mpl::bool_<force_attribute>());
|
Chris@102
|
73 }
|
Chris@102
|
74
|
Chris@102
|
75 RHS rhs;
|
Chris@102
|
76 char const* name;
|
Chris@102
|
77 };
|
Chris@102
|
78
|
Chris@102
|
79 template <typename ID, typename Attribute>
|
Chris@102
|
80 struct rule : parser<rule<ID, Attribute>>
|
Chris@102
|
81 {
|
Chris@102
|
82 typedef ID id;
|
Chris@102
|
83 typedef Attribute attribute_type;
|
Chris@102
|
84 static bool const has_attribute =
|
Chris@102
|
85 !is_same<Attribute, unused_type>::value;
|
Chris@102
|
86 static bool const handles_container =
|
Chris@102
|
87 traits::is_container<Attribute>::value;
|
Chris@102
|
88
|
Chris@102
|
89 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
|
Chris@102
|
90 rule() : name(typeid(rule).name()) {}
|
Chris@102
|
91 #else
|
Chris@102
|
92 rule() : name("unnamed") {}
|
Chris@102
|
93 #endif
|
Chris@102
|
94
|
Chris@102
|
95 rule(char const* name)
|
Chris@102
|
96 : name(name) {}
|
Chris@102
|
97
|
Chris@102
|
98 template <typename RHS>
|
Chris@102
|
99 rule_definition<
|
Chris@102
|
100 ID, typename extension::as_parser<RHS>::value_type, Attribute, false>
|
Chris@102
|
101 operator=(RHS const& rhs) const
|
Chris@102
|
102 {
|
Chris@102
|
103 return {as_parser(rhs), name};
|
Chris@102
|
104 }
|
Chris@102
|
105
|
Chris@102
|
106 template <typename RHS>
|
Chris@102
|
107 rule_definition<
|
Chris@102
|
108 ID, typename extension::as_parser<RHS>::value_type, Attribute, true>
|
Chris@102
|
109 operator%=(RHS const& rhs) const
|
Chris@102
|
110 {
|
Chris@102
|
111 return {as_parser(rhs), name};
|
Chris@102
|
112 }
|
Chris@102
|
113
|
Chris@102
|
114
|
Chris@102
|
115 template <typename Iterator, typename Context, typename Attribute_>
|
Chris@102
|
116 bool parse(Iterator& first, Iterator const& last
|
Chris@102
|
117 , Context const& context, unused_type, Attribute_& attr) const
|
Chris@102
|
118 {
|
Chris@102
|
119 return parse_rule(*this, first, last, context, attr);
|
Chris@102
|
120 }
|
Chris@102
|
121
|
Chris@102
|
122 char const* name;
|
Chris@102
|
123 };
|
Chris@102
|
124
|
Chris@102
|
125 namespace traits
|
Chris@102
|
126 {
|
Chris@102
|
127 template <typename T, typename Enable = void>
|
Chris@102
|
128 struct is_rule : mpl::false_ {};
|
Chris@102
|
129
|
Chris@102
|
130 template <typename ID, typename Attribute>
|
Chris@102
|
131 struct is_rule<rule<ID, Attribute>> : mpl::true_ {};
|
Chris@102
|
132
|
Chris@102
|
133 template <typename ID, typename Attribute, typename RHS, bool force_attribute>
|
Chris@102
|
134 struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute>> : mpl::true_ {};
|
Chris@102
|
135 }
|
Chris@102
|
136
|
Chris@102
|
137 template <typename T>
|
Chris@102
|
138 struct get_info<T, typename enable_if<traits::is_rule<T>>::type>
|
Chris@102
|
139 {
|
Chris@102
|
140 typedef std::string result_type;
|
Chris@102
|
141 std::string operator()(T const& r) const
|
Chris@102
|
142 {
|
Chris@102
|
143 return r.name;
|
Chris@102
|
144 }
|
Chris@102
|
145 };
|
Chris@102
|
146
|
Chris@102
|
147 #define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \
|
Chris@102
|
148 template <typename Iterator, typename Context, typename Attribute> \
|
Chris@102
|
149 bool parse_rule( \
|
Chris@102
|
150 rule_type rule_ \
|
Chris@102
|
151 , Iterator& first, Iterator const& last \
|
Chris@102
|
152 , Context const& context, Attribute& attr); \
|
Chris@102
|
153 /***/
|
Chris@102
|
154
|
Chris@102
|
155 #define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH( \
|
Chris@102
|
156 BOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
|
Chris@102
|
157 /***/
|
Chris@102
|
158
|
Chris@102
|
159 #define BOOST_SPIRIT_DEFINE_(r, data, def) \
|
Chris@102
|
160 template <typename Iterator, typename Context, typename Attribute> \
|
Chris@102
|
161 inline bool parse_rule( \
|
Chris@102
|
162 decltype(def)::lhs_type rule_ \
|
Chris@102
|
163 , Iterator& first, Iterator const& last \
|
Chris@102
|
164 , Context const& context, Attribute& attr) \
|
Chris@102
|
165 { \
|
Chris@102
|
166 using boost::spirit::x3::unused; \
|
Chris@102
|
167 auto const& def_ = (def); \
|
Chris@102
|
168 return def_.parse(first, last, context, unused, attr); \
|
Chris@102
|
169 } \
|
Chris@102
|
170 /***/
|
Chris@102
|
171
|
Chris@102
|
172 #define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH( \
|
Chris@102
|
173 BOOST_SPIRIT_DEFINE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
|
Chris@102
|
174 /***/
|
Chris@102
|
175
|
Chris@102
|
176 #define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \
|
Chris@102
|
177 template bool parse_rule<Iterator, Context, rule_type::attribute_type>( \
|
Chris@102
|
178 rule_type rule_ \
|
Chris@102
|
179 , Iterator& first, Iterator const& last \
|
Chris@102
|
180 , Context const& context, rule_type::attribute_type& attr); \
|
Chris@102
|
181 /***/
|
Chris@102
|
182
|
Chris@102
|
183
|
Chris@102
|
184 }}}
|
Chris@102
|
185
|
Chris@102
|
186 #endif
|