Chris@16
|
1 // Copyright (c) 2001-2011 Hartmut Kaiser
|
Chris@16
|
2 // Copyright (c) 2001-2011 Joel de Guzman
|
Chris@16
|
3 // Copyright (c) 2010 Bryce Lelbach
|
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_LEX_ARGUMENT_JUNE_07_2009_1106AM)
|
Chris@16
|
10 #define BOOST_SPIRIT_LEX_ARGUMENT_JUNE_07_2009_1106AM
|
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/spirit/include/phoenix_core.hpp>
|
Chris@16
|
17 #include <boost/spirit/include/phoenix_operator.hpp>
|
Chris@16
|
18 #include <boost/spirit/home/support/string_traits.hpp>
|
Chris@16
|
19 #include <boost/spirit/home/lex/argument_phoenix.hpp>
|
Chris@16
|
20 #include <boost/fusion/include/at.hpp>
|
Chris@16
|
21 #include <boost/mpl/at.hpp>
|
Chris@16
|
22 #include <boost/mpl/bool.hpp>
|
Chris@16
|
23 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
24 #include <boost/type_traits/remove_const.hpp>
|
Chris@16
|
25 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
26
|
Chris@16
|
27 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
28 namespace boost { namespace spirit { namespace lex
|
Chris@16
|
29 {
|
Chris@16
|
30 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
31 // The state_getter is a Phoenix actor used to access the name of the
|
Chris@16
|
32 // current lexer state by calling get_state_name() on the context (which
|
Chris@16
|
33 // is the 5th parameter to any lexer semantic actions).
|
Chris@16
|
34 //
|
Chris@16
|
35 // This Phoenix actor is invoked whenever the placeholder '_state' is used
|
Chris@16
|
36 // as a rvalue inside a lexer semantic action:
|
Chris@16
|
37 //
|
Chris@16
|
38 // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
|
Chris@16
|
39 // this->self = identifier [ std::cout << _state ];
|
Chris@16
|
40 //
|
Chris@16
|
41 // The example shows how to print the lexer state after matching a token
|
Chris@16
|
42 // 'identifier'.
|
Chris@16
|
43 struct state_getter
|
Chris@16
|
44 {
|
Chris@16
|
45 typedef mpl::true_ no_nullary;
|
Chris@16
|
46
|
Chris@16
|
47 template <typename Env>
|
Chris@16
|
48 struct result
|
Chris@16
|
49 {
|
Chris@16
|
50 typedef
|
Chris@16
|
51 typename remove_reference<
|
Chris@16
|
52 typename remove_const<
|
Chris@16
|
53 typename mpl::at_c<typename Env::args_type, 4>::type
|
Chris@16
|
54 >::type
|
Chris@16
|
55 >::type
|
Chris@16
|
56 context_type;
|
Chris@16
|
57
|
Chris@16
|
58 typedef typename context_type::state_name_type type;
|
Chris@16
|
59 };
|
Chris@16
|
60
|
Chris@16
|
61 template <typename Env>
|
Chris@16
|
62 typename result<Env>::type
|
Chris@16
|
63 eval(Env const& env) const
|
Chris@16
|
64 {
|
Chris@16
|
65 return fusion::at_c<4>(env.args()).get_state_name();
|
Chris@16
|
66 }
|
Chris@16
|
67 };
|
Chris@16
|
68
|
Chris@16
|
69 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
70 // The state_setter is a Phoenix actor used to change the name of the
|
Chris@16
|
71 // current lexer state by calling set_state_name() on the context (which
|
Chris@16
|
72 // is the 5th parameter to any lexer semantic actions).
|
Chris@16
|
73 //
|
Chris@16
|
74 // This Phoenix actor is invoked whenever the placeholder '_state' is used
|
Chris@16
|
75 // as a lvalue inside a lexer semantic action:
|
Chris@16
|
76 //
|
Chris@16
|
77 // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
|
Chris@16
|
78 // this->self = identifier [ _state = "SOME_LEXER_STATE" ];
|
Chris@16
|
79 //
|
Chris@16
|
80 // The example shows how to change the lexer state after matching a token
|
Chris@16
|
81 // 'identifier'.
|
Chris@16
|
82 template <typename Actor>
|
Chris@16
|
83 struct state_setter
|
Chris@16
|
84 {
|
Chris@16
|
85 typedef mpl::true_ no_nullary;
|
Chris@16
|
86
|
Chris@16
|
87 template <typename Env>
|
Chris@16
|
88 struct result
|
Chris@16
|
89 {
|
Chris@16
|
90 typedef void type;
|
Chris@16
|
91 };
|
Chris@16
|
92
|
Chris@16
|
93 template <typename Env>
|
Chris@16
|
94 void eval(Env const& env) const
|
Chris@16
|
95 {
|
Chris@16
|
96 typedef
|
Chris@16
|
97 typename remove_reference<
|
Chris@16
|
98 typename remove_const<
|
Chris@16
|
99 typename mpl::at_c<typename Env::args_type, 4>::type
|
Chris@16
|
100 >::type
|
Chris@16
|
101 >::type
|
Chris@16
|
102 context_type;
|
Chris@16
|
103
|
Chris@16
|
104 typedef typename context_type::state_name_type string;
|
Chris@16
|
105
|
Chris@16
|
106 fusion::at_c<4>(env.args()).set_state_name(
|
Chris@16
|
107 traits::get_c_string(actor_.eval(env)));
|
Chris@16
|
108 }
|
Chris@16
|
109
|
Chris@16
|
110 state_setter(Actor const& actor)
|
Chris@16
|
111 : actor_(actor) {}
|
Chris@16
|
112
|
Chris@16
|
113 // see explanation for this constructor at the end of this file
|
Chris@16
|
114 #ifndef BOOST_SPIRIT_USE_PHOENIX_V3
|
Chris@16
|
115 state_setter(phoenix::actor<state_getter>, Actor const& actor)
|
Chris@16
|
116 : actor_(actor) {}
|
Chris@16
|
117 #endif
|
Chris@16
|
118
|
Chris@16
|
119 Actor actor_;
|
Chris@16
|
120 };
|
Chris@16
|
121
|
Chris@16
|
122 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
123 // The value_getter is used to create the _val placeholder, which is a
|
Chris@16
|
124 // Phoenix actor used to access the value of the current token.
|
Chris@16
|
125 //
|
Chris@16
|
126 // This Phoenix actor is invoked whenever the placeholder '_val' is used
|
Chris@16
|
127 // as a rvalue inside a lexer semantic action:
|
Chris@16
|
128 //
|
Chris@16
|
129 // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
|
Chris@16
|
130 // this->self = identifier [ std::cout << _val ];
|
Chris@16
|
131 //
|
Chris@16
|
132 // The example shows how to use _val to print the identifier name (which
|
Chris@16
|
133 // is the initial token value).
|
Chris@16
|
134 struct value_getter
|
Chris@16
|
135 {
|
Chris@16
|
136 typedef mpl::true_ no_nullary;
|
Chris@16
|
137
|
Chris@16
|
138 template <typename Env>
|
Chris@16
|
139 struct result
|
Chris@16
|
140 {
|
Chris@16
|
141 typedef
|
Chris@16
|
142 typename remove_reference<
|
Chris@16
|
143 typename remove_const<
|
Chris@16
|
144 typename mpl::at_c<typename Env::args_type, 4>::type
|
Chris@16
|
145 >::type
|
Chris@16
|
146 >::type
|
Chris@16
|
147 context_type;
|
Chris@16
|
148
|
Chris@16
|
149 typedef typename context_type::get_value_type type;
|
Chris@16
|
150 };
|
Chris@16
|
151
|
Chris@16
|
152 template <typename Env>
|
Chris@16
|
153 typename result<Env>::type
|
Chris@16
|
154 eval(Env const& env) const
|
Chris@16
|
155 {
|
Chris@16
|
156 return fusion::at_c<4>(env.args()).get_value();
|
Chris@16
|
157 }
|
Chris@16
|
158 };
|
Chris@16
|
159
|
Chris@16
|
160 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
161 // The value_setter is a Phoenix actor used to change the name of the
|
Chris@16
|
162 // current lexer state by calling set_state_name() on the context (which
|
Chris@16
|
163 // is the 5th parameter to any lexer semantic actions).
|
Chris@16
|
164 //
|
Chris@16
|
165 // This Phoenix actor is invoked whenever the placeholder '_val' is used
|
Chris@16
|
166 // as a lvalue inside a lexer semantic action:
|
Chris@16
|
167 //
|
Chris@16
|
168 // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
|
Chris@16
|
169 // this->self = identifier [ _val = "identifier" ];
|
Chris@16
|
170 //
|
Chris@16
|
171 // The example shows how to change the token value after matching a token
|
Chris@16
|
172 // 'identifier'.
|
Chris@16
|
173 template <typename Actor>
|
Chris@16
|
174 struct value_setter
|
Chris@16
|
175 {
|
Chris@16
|
176 typedef mpl::true_ no_nullary;
|
Chris@16
|
177
|
Chris@16
|
178 template <typename Env>
|
Chris@16
|
179 struct result
|
Chris@16
|
180 {
|
Chris@16
|
181 typedef void type;
|
Chris@16
|
182 };
|
Chris@16
|
183
|
Chris@16
|
184 template <typename Env>
|
Chris@16
|
185 void eval(Env const& env) const
|
Chris@16
|
186 {
|
Chris@16
|
187 fusion::at_c<4>(env.args()).set_value(actor_.eval(env));
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 value_setter(Actor const& actor)
|
Chris@16
|
191 : actor_(actor) {}
|
Chris@16
|
192
|
Chris@16
|
193 #ifndef BOOST_SPIRIT_USE_PHOENIX_V3
|
Chris@16
|
194 // see explanation for this constructor at the end of this file
|
Chris@16
|
195 value_setter(phoenix::actor<value_getter>, Actor const& actor)
|
Chris@16
|
196 : actor_(actor) {}
|
Chris@16
|
197 #endif
|
Chris@16
|
198
|
Chris@16
|
199 Actor actor_;
|
Chris@16
|
200 };
|
Chris@16
|
201
|
Chris@16
|
202 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
203 // The eoi_getter is used to create the _eoi placeholder, which is a
|
Chris@16
|
204 // Phoenix actor used to access the end of input iterator pointing to the
|
Chris@16
|
205 // end of the underlying input sequence.
|
Chris@16
|
206 //
|
Chris@16
|
207 // This actor is invoked whenever the placeholder '_eoi' is used in a
|
Chris@16
|
208 // lexer semantic action:
|
Chris@16
|
209 //
|
Chris@16
|
210 // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
|
Chris@16
|
211 // this->self = identifier
|
Chris@16
|
212 // [ std::cout << construct_<std::string>(_end, _eoi) ];
|
Chris@16
|
213 //
|
Chris@16
|
214 // The example shows how to use _eoi to print all remaining input after
|
Chris@16
|
215 // matching a token 'identifier'.
|
Chris@16
|
216 struct eoi_getter
|
Chris@16
|
217 {
|
Chris@16
|
218 typedef mpl::true_ no_nullary;
|
Chris@16
|
219
|
Chris@16
|
220 template <typename Env>
|
Chris@16
|
221 struct result
|
Chris@16
|
222 {
|
Chris@16
|
223 typedef
|
Chris@16
|
224 typename remove_reference<
|
Chris@16
|
225 typename remove_const<
|
Chris@16
|
226 typename mpl::at_c<typename Env::args_type, 4>::type
|
Chris@16
|
227 >::type
|
Chris@16
|
228 >::type
|
Chris@16
|
229 context_type;
|
Chris@16
|
230
|
Chris@16
|
231 typedef typename context_type::base_iterator_type const& type;
|
Chris@16
|
232 };
|
Chris@16
|
233
|
Chris@16
|
234 template <typename Env>
|
Chris@16
|
235 typename result<Env>::type
|
Chris@16
|
236 eval(Env const& env) const
|
Chris@16
|
237 {
|
Chris@16
|
238 return fusion::at_c<4>(env.args()).get_eoi();
|
Chris@16
|
239 }
|
Chris@16
|
240 };
|
Chris@16
|
241
|
Chris@16
|
242 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
243 // '_start' and '_end' may be used to access the start and the end of
|
Chris@16
|
244 // the matched sequence of the current token
|
Chris@16
|
245 typedef phoenix::arg_names::_1_type _start_type;
|
Chris@16
|
246 typedef phoenix::arg_names::_2_type _end_type;
|
Chris@16
|
247 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
Chris@16
|
248 _start_type const _start = _start_type();
|
Chris@16
|
249 _end_type const _end = _end_type();
|
Chris@16
|
250 #endif
|
Chris@16
|
251
|
Chris@16
|
252 // We are reusing the placeholder '_pass' to access and change the pass
|
Chris@16
|
253 // status of the current match (see support/argument.hpp for its
|
Chris@16
|
254 // definition).
|
Chris@16
|
255 // typedef phoenix::arg_names::_3_type _pass_type;
|
Chris@16
|
256 using boost::spirit::_pass_type;
|
Chris@16
|
257 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
Chris@16
|
258 using boost::spirit::_pass;
|
Chris@16
|
259 #endif
|
Chris@16
|
260
|
Chris@16
|
261 // '_tokenid' may be used to access and change the tokenid of the current
|
Chris@16
|
262 // token
|
Chris@16
|
263 typedef phoenix::arg_names::_4_type _tokenid_type;
|
Chris@16
|
264 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
Chris@16
|
265 _tokenid_type const _tokenid = _tokenid_type();
|
Chris@16
|
266 #endif
|
Chris@16
|
267
|
Chris@16
|
268 typedef phoenix::actor<value_context> _val_type;
|
Chris@16
|
269 typedef phoenix::actor<state_context> _state_type;
|
Chris@16
|
270 typedef phoenix::actor<eoi_getter> _eoi_type;
|
Chris@16
|
271 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
Chris@16
|
272 // '_val' may be used to access and change the token value of the current
|
Chris@16
|
273 // token
|
Chris@16
|
274 _val_type const _val = _val_type();
|
Chris@16
|
275 // _state may be used to access and change the name of the current lexer
|
Chris@16
|
276 // state
|
Chris@16
|
277 _state_type const _state = _state_type();
|
Chris@16
|
278 // '_eoi' may be used to access the end of input iterator of the input
|
Chris@16
|
279 // stream used by the lexer to match tokens from
|
Chris@16
|
280 _eoi_type const _eoi = _eoi_type();
|
Chris@16
|
281 #endif
|
Chris@16
|
282 }}}
|
Chris@16
|
283
|
Chris@16
|
284 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
285 #ifndef BOOST_SPIRIT_USE_PHOENIX_V3
|
Chris@16
|
286 namespace boost { namespace phoenix
|
Chris@16
|
287 {
|
Chris@16
|
288 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
289 // The specialization of as_actor_base<> below is needed to convert all
|
Chris@16
|
290 // occurrences of _state in places where it's used as a rvalue into the
|
Chris@16
|
291 // proper Phoenix actor (spirit::state_getter) accessing the lexer state.
|
Chris@16
|
292 template<>
|
Chris@16
|
293 struct as_actor_base<actor<spirit::lex::state_context> >
|
Chris@16
|
294 {
|
Chris@16
|
295 typedef spirit::lex::state_getter type;
|
Chris@16
|
296
|
Chris@16
|
297 static spirit::lex::state_getter
|
Chris@16
|
298 convert(actor<spirit::lex::state_context>)
|
Chris@16
|
299 {
|
Chris@16
|
300 return spirit::lex::state_getter();
|
Chris@16
|
301 }
|
Chris@16
|
302 };
|
Chris@16
|
303
|
Chris@16
|
304 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
305 // The specialization of as_composite<> below is needed to convert all
|
Chris@16
|
306 // assignments to _state (places where it's used as a lvalue) into the
|
Chris@16
|
307 // proper Phoenix actor (spirit::state_setter) allowing to change the
|
Chris@16
|
308 // lexer state.
|
Chris@16
|
309 template <typename RHS>
|
Chris@16
|
310 struct as_composite<assign_eval, actor<spirit::lex::state_context>, RHS>
|
Chris@16
|
311 {
|
Chris@16
|
312 // For an assignment to _state (a spirit::state_context actor), this
|
Chris@16
|
313 // specialization makes Phoenix's compose() function construct a
|
Chris@16
|
314 // spirit::state_setter actor from 1. the LHS, a spirit::state_getter
|
Chris@16
|
315 // actor (due to the specialization of as_actor_base<> above),
|
Chris@16
|
316 // and 2. the RHS actor.
|
Chris@16
|
317 // This is why spirit::state_setter needs a constructor which takes
|
Chris@16
|
318 // a dummy spirit::state_getter as its first argument in addition
|
Chris@16
|
319 // to its real, second argument (the RHS actor).
|
Chris@16
|
320 typedef spirit::lex::state_setter<typename as_actor<RHS>::type> type;
|
Chris@16
|
321 };
|
Chris@16
|
322
|
Chris@16
|
323 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
324 // The specialization of as_actor_base<> below is needed to convert all
|
Chris@16
|
325 // occurrences of _val in places where it's used as a rvalue into the
|
Chris@16
|
326 // proper Phoenix actor (spirit::value_getter) accessing the token value.
|
Chris@16
|
327 template<>
|
Chris@16
|
328 struct as_actor_base<actor<spirit::lex::value_context> >
|
Chris@16
|
329 {
|
Chris@16
|
330 typedef spirit::lex::value_getter type;
|
Chris@16
|
331
|
Chris@16
|
332 static spirit::lex::value_getter
|
Chris@16
|
333 convert(actor<spirit::lex::value_context>)
|
Chris@16
|
334 {
|
Chris@16
|
335 return spirit::lex::value_getter();
|
Chris@16
|
336 }
|
Chris@16
|
337 };
|
Chris@16
|
338
|
Chris@16
|
339 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
340 // The specialization of as_composite<> below is needed to convert all
|
Chris@16
|
341 // assignments to _val (places where it's used as a lvalue) into the
|
Chris@16
|
342 // proper Phoenix actor (spirit::value_setter) allowing to change the
|
Chris@16
|
343 // token value.
|
Chris@16
|
344 template <typename RHS>
|
Chris@16
|
345 struct as_composite<assign_eval, actor<spirit::lex::value_context>, RHS>
|
Chris@16
|
346 {
|
Chris@16
|
347 // For an assignment to _val (a spirit::value_context actor), this
|
Chris@16
|
348 // specialization makes Phoenix's compose() function construct a
|
Chris@16
|
349 // spirit::value_setter actor from 1. the LHS, a spirit::value_getter
|
Chris@16
|
350 // actor (due to the specialization of as_actor_base<> above),
|
Chris@16
|
351 // and 2. the RHS actor.
|
Chris@16
|
352 // This is why spirit::value_setter needs a constructor which takes
|
Chris@16
|
353 // a dummy spirit::value_getter as its first argument in addition
|
Chris@16
|
354 // to its real, second argument (the RHS actor).
|
Chris@16
|
355 typedef spirit::lex::value_setter<typename as_actor<RHS>::type> type;
|
Chris@16
|
356 };
|
Chris@16
|
357 }}
|
Chris@16
|
358 #endif
|
Chris@16
|
359
|
Chris@16
|
360 #undef SPIRIT_DECLARE_ARG
|
Chris@16
|
361 #endif
|
Chris@16
|
362
|