Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2011 Joel de Guzman
|
Chris@16
|
3 Copyright (c) 2001-2011 Hartmut Kaiser
|
Chris@16
|
4 Copyright (c) 2011 Thomas Heller
|
Chris@16
|
5
|
Chris@16
|
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 ==============================================================================*/
|
Chris@16
|
9 #if !defined(BOOST_SPIRIT_CONTEXT_OCTOBER_31_2008_0654PM)
|
Chris@16
|
10 #define BOOST_SPIRIT_CONTEXT_OCTOBER_31_2008_0654PM
|
Chris@16
|
11
|
Chris@16
|
12 #if defined(_MSC_VER)
|
Chris@16
|
13 #pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
Chris@16
|
17 #include <boost/spirit/include/phoenix_core.hpp>
|
Chris@16
|
18 #include <boost/spirit/home/support/nonterminal/expand_arg.hpp>
|
Chris@16
|
19 #include <boost/spirit/home/support/assert_msg.hpp>
|
Chris@16
|
20 #include <boost/spirit/home/support/argument.hpp>
|
Chris@16
|
21 #include <boost/spirit/home/support/limits.hpp>
|
Chris@16
|
22 #include <boost/fusion/include/at.hpp>
|
Chris@16
|
23 #include <boost/fusion/include/size.hpp>
|
Chris@16
|
24 #include <boost/fusion/include/as_list.hpp>
|
Chris@16
|
25 #include <boost/fusion/include/transform.hpp>
|
Chris@16
|
26 #include <boost/mpl/size.hpp>
|
Chris@16
|
27 #include <boost/mpl/at.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
30 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
Chris@16
|
31
|
Chris@16
|
32 #define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \
|
Chris@16
|
33 typedef phoenix::actor<attribute<n> > \
|
Chris@16
|
34 BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
|
Chris@16
|
35 phoenix::actor<attribute<n> > const \
|
Chris@16
|
36 BOOST_PP_CAT(_r, n) = BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type)();
|
Chris@16
|
37 /***/
|
Chris@16
|
38 #define SPIRIT_USING_ATTRIBUTE(z, n, data) \
|
Chris@16
|
39 using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
|
Chris@16
|
40 using spirit::BOOST_PP_CAT(_r, n); \
|
Chris@16
|
41 /***/
|
Chris@16
|
42
|
Chris@16
|
43 #else
|
Chris@16
|
44
|
Chris@16
|
45 #define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \
|
Chris@16
|
46 typedef phoenix::actor<attribute<n> > \
|
Chris@16
|
47 BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
|
Chris@16
|
48 /***/
|
Chris@16
|
49 #define SPIRIT_USING_ATTRIBUTE(z, n, data) \
|
Chris@16
|
50 using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
|
Chris@16
|
51 /***/
|
Chris@16
|
52
|
Chris@16
|
53 #endif
|
Chris@16
|
54
|
Chris@16
|
55 namespace boost { namespace spirit
|
Chris@16
|
56 {
|
Chris@16
|
57 template <int>
|
Chris@16
|
58 struct attribute;
|
Chris@16
|
59
|
Chris@16
|
60 template <int>
|
Chris@16
|
61 struct local_variable;
|
Chris@16
|
62 }}
|
Chris@16
|
63
|
Chris@16
|
64 BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
|
Chris@16
|
65 template <int N>
|
Chris@16
|
66 , boost::spirit::attribute<N>
|
Chris@16
|
67 , mpl::false_ // is not nullary
|
Chris@16
|
68 , v2_eval(
|
Chris@16
|
69 proto::make<
|
Chris@16
|
70 boost::spirit::attribute<N>()
|
Chris@16
|
71 >
|
Chris@16
|
72 , proto::call<
|
Chris@16
|
73 functional::env(proto::_state)
|
Chris@16
|
74 >
|
Chris@16
|
75 )
|
Chris@16
|
76 )
|
Chris@16
|
77
|
Chris@16
|
78 BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
|
Chris@16
|
79 template <int N>
|
Chris@16
|
80 , boost::spirit::local_variable<N>
|
Chris@16
|
81 , mpl::false_ // is not nullary
|
Chris@16
|
82 , v2_eval(
|
Chris@16
|
83 proto::make<
|
Chris@16
|
84 boost::spirit::local_variable<N>()
|
Chris@16
|
85 >
|
Chris@16
|
86 , proto::call<
|
Chris@16
|
87 functional::env(proto::_state)
|
Chris@16
|
88 >
|
Chris@16
|
89 )
|
Chris@16
|
90 )
|
Chris@16
|
91
|
Chris@16
|
92 namespace boost { namespace spirit
|
Chris@16
|
93 {
|
Chris@16
|
94 template <typename Attributes, typename Locals>
|
Chris@16
|
95 struct context
|
Chris@16
|
96 {
|
Chris@16
|
97 typedef Attributes attributes_type;
|
Chris@16
|
98 typedef Locals locals_type;
|
Chris@16
|
99
|
Chris@16
|
100 context(typename Attributes::car_type attribute)
|
Chris@101
|
101 : attributes(attribute, fusion::nil_()), locals() {}
|
Chris@16
|
102
|
Chris@16
|
103 template <typename Args, typename Context>
|
Chris@16
|
104 context(
|
Chris@16
|
105 typename Attributes::car_type attribute
|
Chris@16
|
106 , Args const& args
|
Chris@16
|
107 , Context& caller_context
|
Chris@16
|
108 ) : attributes(
|
Chris@16
|
109 attribute
|
Chris@16
|
110 , fusion::as_list(
|
Chris@16
|
111 fusion::transform(
|
Chris@16
|
112 args
|
Chris@16
|
113 , detail::expand_arg<Context>(caller_context)
|
Chris@16
|
114 )
|
Chris@16
|
115 )
|
Chris@16
|
116 )
|
Chris@16
|
117 , locals() {}
|
Chris@16
|
118
|
Chris@16
|
119 context(Attributes const& attributes_)
|
Chris@16
|
120 : attributes(attributes_), locals() {}
|
Chris@16
|
121
|
Chris@16
|
122 Attributes attributes; // The attributes
|
Chris@16
|
123 Locals locals; // Local variables
|
Chris@16
|
124 };
|
Chris@16
|
125
|
Chris@16
|
126 template <typename Context>
|
Chris@16
|
127 struct attributes_of
|
Chris@16
|
128 {
|
Chris@16
|
129 typedef typename Context::attributes_type type;
|
Chris@16
|
130 };
|
Chris@16
|
131
|
Chris@16
|
132 template <typename Context>
|
Chris@16
|
133 struct attributes_of<Context const>
|
Chris@16
|
134 {
|
Chris@16
|
135 typedef typename Context::attributes_type const type;
|
Chris@16
|
136 };
|
Chris@16
|
137
|
Chris@16
|
138 template <typename Context>
|
Chris@16
|
139 struct attributes_of<Context &>
|
Chris@16
|
140 : attributes_of<Context>
|
Chris@16
|
141 {};
|
Chris@16
|
142
|
Chris@16
|
143 template <typename Context>
|
Chris@16
|
144 struct locals_of
|
Chris@16
|
145 {
|
Chris@16
|
146 typedef typename Context::locals_type type;
|
Chris@16
|
147 };
|
Chris@16
|
148
|
Chris@16
|
149 template <typename Context>
|
Chris@16
|
150 struct locals_of<Context const>
|
Chris@16
|
151 {
|
Chris@16
|
152 typedef typename Context::locals_type const type;
|
Chris@16
|
153 };
|
Chris@16
|
154
|
Chris@16
|
155 template <typename Context>
|
Chris@16
|
156 struct locals_of<Context &>
|
Chris@16
|
157 {
|
Chris@16
|
158 typedef typename Context::locals_type type;
|
Chris@16
|
159 };
|
Chris@16
|
160
|
Chris@16
|
161 template <int N>
|
Chris@16
|
162 struct attribute
|
Chris@16
|
163 {
|
Chris@16
|
164 typedef mpl::true_ no_nullary;
|
Chris@16
|
165
|
Chris@16
|
166 template <typename Env>
|
Chris@16
|
167 struct result
|
Chris@16
|
168 {
|
Chris@16
|
169 typedef typename
|
Chris@16
|
170 attributes_of<typename
|
Chris@16
|
171 mpl::at_c<typename Env::args_type, 1>::type
|
Chris@16
|
172 >::type
|
Chris@16
|
173 attributes_type;
|
Chris@16
|
174
|
Chris@16
|
175 typedef typename
|
Chris@16
|
176 fusion::result_of::size<attributes_type>::type
|
Chris@16
|
177 attributes_size;
|
Chris@16
|
178
|
Chris@16
|
179 // report invalid argument not found (N is out of bounds)
|
Chris@16
|
180 BOOST_SPIRIT_ASSERT_MSG(
|
Chris@16
|
181 (N < attributes_size::value),
|
Chris@16
|
182 index_is_out_of_bounds, ());
|
Chris@16
|
183
|
Chris@16
|
184 typedef typename
|
Chris@16
|
185 fusion::result_of::at_c<attributes_type, N>::type
|
Chris@16
|
186 type;
|
Chris@16
|
187 };
|
Chris@16
|
188
|
Chris@16
|
189 template <typename Env>
|
Chris@16
|
190 typename result<Env>::type
|
Chris@16
|
191 eval(Env const& env) const
|
Chris@16
|
192 {
|
Chris@16
|
193 return fusion::at_c<N>((fusion::at_c<1>(env.args())).attributes);
|
Chris@16
|
194 }
|
Chris@16
|
195 };
|
Chris@16
|
196
|
Chris@16
|
197 template <int N>
|
Chris@16
|
198 struct local_variable
|
Chris@16
|
199 {
|
Chris@16
|
200 typedef mpl::true_ no_nullary;
|
Chris@16
|
201
|
Chris@16
|
202 template <typename Env>
|
Chris@16
|
203 struct result
|
Chris@16
|
204 {
|
Chris@16
|
205 typedef typename
|
Chris@16
|
206 locals_of<typename
|
Chris@16
|
207 mpl::at_c<typename Env::args_type, 1>::type
|
Chris@16
|
208 >::type
|
Chris@16
|
209 locals_type;
|
Chris@16
|
210
|
Chris@16
|
211 typedef typename
|
Chris@16
|
212 fusion::result_of::size<locals_type>::type
|
Chris@16
|
213 locals_size;
|
Chris@16
|
214
|
Chris@16
|
215 // report invalid argument not found (N is out of bounds)
|
Chris@16
|
216 BOOST_SPIRIT_ASSERT_MSG(
|
Chris@16
|
217 (N < locals_size::value),
|
Chris@16
|
218 index_is_out_of_bounds, ());
|
Chris@16
|
219
|
Chris@16
|
220 typedef typename
|
Chris@16
|
221 fusion::result_of::at_c<locals_type, N>::type
|
Chris@16
|
222 type;
|
Chris@16
|
223 };
|
Chris@16
|
224
|
Chris@16
|
225 template <typename Env>
|
Chris@16
|
226 typename result<Env>::type
|
Chris@16
|
227 eval(Env const& env) const
|
Chris@16
|
228 {
|
Chris@16
|
229 return get_arg<N>((fusion::at_c<1>(env.args())).locals);
|
Chris@16
|
230 }
|
Chris@16
|
231 };
|
Chris@16
|
232
|
Chris@16
|
233 typedef phoenix::actor<attribute<0> > _val_type;
|
Chris@16
|
234 typedef phoenix::actor<attribute<0> > _r0_type;
|
Chris@16
|
235 typedef phoenix::actor<attribute<1> > _r1_type;
|
Chris@16
|
236 typedef phoenix::actor<attribute<2> > _r2_type;
|
Chris@16
|
237
|
Chris@16
|
238 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
Chris@16
|
239 // _val refers to the 'return' value of a rule (same as _r0)
|
Chris@16
|
240 // _r1, _r2, ... refer to the rule arguments
|
Chris@16
|
241 _val_type const _val = _val_type();
|
Chris@16
|
242 _r0_type const _r0 = _r0_type();
|
Chris@16
|
243 _r1_type const _r1 = _r1_type();
|
Chris@16
|
244 _r2_type const _r2 = _r2_type();
|
Chris@16
|
245 #endif
|
Chris@16
|
246
|
Chris@16
|
247 // Bring in the rest of the attributes (_r4 .. _rN+1), using PP
|
Chris@16
|
248 BOOST_PP_REPEAT_FROM_TO(
|
Chris@16
|
249 3, SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_DECLARE_ATTRIBUTE, _)
|
Chris@16
|
250
|
Chris@16
|
251 typedef phoenix::actor<local_variable<0> > _a_type;
|
Chris@16
|
252 typedef phoenix::actor<local_variable<1> > _b_type;
|
Chris@16
|
253 typedef phoenix::actor<local_variable<2> > _c_type;
|
Chris@16
|
254 typedef phoenix::actor<local_variable<3> > _d_type;
|
Chris@16
|
255 typedef phoenix::actor<local_variable<4> > _e_type;
|
Chris@16
|
256 typedef phoenix::actor<local_variable<5> > _f_type;
|
Chris@16
|
257 typedef phoenix::actor<local_variable<6> > _g_type;
|
Chris@16
|
258 typedef phoenix::actor<local_variable<7> > _h_type;
|
Chris@16
|
259 typedef phoenix::actor<local_variable<8> > _i_type;
|
Chris@16
|
260 typedef phoenix::actor<local_variable<9> > _j_type;
|
Chris@16
|
261
|
Chris@16
|
262 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
Chris@16
|
263 // _a, _b, ... refer to the local variables of a rule
|
Chris@16
|
264 _a_type const _a = _a_type();
|
Chris@16
|
265 _b_type const _b = _b_type();
|
Chris@16
|
266 _c_type const _c = _c_type();
|
Chris@16
|
267 _d_type const _d = _d_type();
|
Chris@16
|
268 _e_type const _e = _e_type();
|
Chris@16
|
269 _f_type const _f = _f_type();
|
Chris@16
|
270 _g_type const _g = _g_type();
|
Chris@16
|
271 _h_type const _h = _h_type();
|
Chris@16
|
272 _i_type const _i = _i_type();
|
Chris@16
|
273 _j_type const _j = _j_type();
|
Chris@16
|
274 #endif
|
Chris@16
|
275
|
Chris@16
|
276 // You can bring these in with the using directive
|
Chris@16
|
277 // without worrying about bringing in too much.
|
Chris@16
|
278 namespace labels
|
Chris@16
|
279 {
|
Chris@16
|
280 BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
|
Chris@16
|
281 BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
|
Chris@16
|
282
|
Chris@16
|
283 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
Chris@16
|
284 using spirit::_val;
|
Chris@16
|
285 using spirit::_a;
|
Chris@16
|
286 using spirit::_b;
|
Chris@16
|
287 using spirit::_c;
|
Chris@16
|
288 using spirit::_d;
|
Chris@16
|
289 using spirit::_e;
|
Chris@16
|
290 using spirit::_f;
|
Chris@16
|
291 using spirit::_g;
|
Chris@16
|
292 using spirit::_h;
|
Chris@16
|
293 using spirit::_i;
|
Chris@16
|
294 using spirit::_j;
|
Chris@16
|
295 #endif
|
Chris@16
|
296 }
|
Chris@16
|
297 }}
|
Chris@16
|
298
|
Chris@16
|
299 #endif
|