1 | // Copyright (c) 2001-2011 Hartmut Kaiser |
2 | // Copyright (c) 2001-2011 Joel de Guzman |
3 | // Copyright (c) 2010 Bryce Lelbach |
4 | // Copyright (c) 2011 Thomas Heller |
5 | // |
6 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
7 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
8 | |
9 | #if !defined(BOOST_SPIRIT_LEX_ARGUMENT_JUNE_07_2009_1106AM) |
10 | #define BOOST_SPIRIT_LEX_ARGUMENT_JUNE_07_2009_1106AM |
11 | |
12 | #if defined(_MSC_VER) |
13 | #pragma once |
14 | #endif |
15 | |
16 | #include <boost/spirit/home/support/string_traits.hpp> |
17 | #include <boost/spirit/home/lex/argument_phoenix.hpp> |
18 | #include <boost/fusion/include/at.hpp> |
19 | #include <boost/mpl/at.hpp> |
20 | #include <boost/mpl/bool.hpp> |
21 | #include <boost/phoenix/core/actor.hpp> |
22 | #include <boost/phoenix/core/argument.hpp> |
23 | #include <boost/type_traits/is_same.hpp> |
24 | #include <boost/type_traits/remove_const.hpp> |
25 | #include <boost/type_traits/remove_reference.hpp> |
26 | |
27 | /////////////////////////////////////////////////////////////////////////////// |
28 | namespace boost { namespace spirit { namespace lex |
29 | { |
30 | /////////////////////////////////////////////////////////////////////////// |
31 | // The state_getter is a Phoenix actor used to access the name of the |
32 | // current lexer state by calling get_state_name() on the context (which |
33 | // is the 5th parameter to any lexer semantic actions). |
34 | // |
35 | // This Phoenix actor is invoked whenever the placeholder '_state' is used |
36 | // as a rvalue inside a lexer semantic action: |
37 | // |
38 | // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; |
39 | // this->self = identifier [ std::cout << _state ]; |
40 | // |
41 | // The example shows how to print the lexer state after matching a token |
42 | // 'identifier'. |
43 | struct state_getter |
44 | { |
45 | typedef mpl::true_ no_nullary; |
46 | |
47 | template <typename Env> |
48 | struct result |
49 | { |
50 | typedef |
51 | typename remove_reference< |
52 | typename remove_const< |
53 | typename mpl::at_c<typename Env::args_type, 4>::type |
54 | >::type |
55 | >::type |
56 | context_type; |
57 | |
58 | typedef typename context_type::state_name_type type; |
59 | }; |
60 | |
61 | template <typename Env> |
62 | typename result<Env>::type |
63 | eval(Env const& env) const |
64 | { |
65 | return fusion::at_c<4>(env.args()).get_state_name(); |
66 | } |
67 | }; |
68 | |
69 | /////////////////////////////////////////////////////////////////////////// |
70 | // The state_setter is a Phoenix actor used to change the name of the |
71 | // current lexer state by calling set_state_name() on the context (which |
72 | // is the 5th parameter to any lexer semantic actions). |
73 | // |
74 | // This Phoenix actor is invoked whenever the placeholder '_state' is used |
75 | // as a lvalue inside a lexer semantic action: |
76 | // |
77 | // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; |
78 | // this->self = identifier [ _state = "SOME_LEXER_STATE" ]; |
79 | // |
80 | // The example shows how to change the lexer state after matching a token |
81 | // 'identifier'. |
82 | template <typename Actor> |
83 | struct state_setter |
84 | { |
85 | typedef mpl::true_ no_nullary; |
86 | |
87 | template <typename Env> |
88 | struct result |
89 | { |
90 | typedef void type; |
91 | }; |
92 | |
93 | template <typename Env> |
94 | void eval(Env const& env) const |
95 | { |
96 | fusion::at_c<4>(env.args()).set_state_name( |
97 | traits::get_c_string(actor_.eval(env))); |
98 | } |
99 | |
100 | state_setter(Actor const& actor) |
101 | : actor_(actor) {} |
102 | |
103 | Actor actor_; |
104 | }; |
105 | |
106 | /////////////////////////////////////////////////////////////////////////// |
107 | // The value_getter is used to create the _val placeholder, which is a |
108 | // Phoenix actor used to access the value of the current token. |
109 | // |
110 | // This Phoenix actor is invoked whenever the placeholder '_val' is used |
111 | // as a rvalue inside a lexer semantic action: |
112 | // |
113 | // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; |
114 | // this->self = identifier [ std::cout << _val ]; |
115 | // |
116 | // The example shows how to use _val to print the identifier name (which |
117 | // is the initial token value). |
118 | struct value_getter |
119 | { |
120 | typedef mpl::true_ no_nullary; |
121 | |
122 | template <typename Env> |
123 | struct result |
124 | { |
125 | typedef |
126 | typename remove_reference< |
127 | typename remove_const< |
128 | typename mpl::at_c<typename Env::args_type, 4>::type |
129 | >::type |
130 | >::type |
131 | context_type; |
132 | |
133 | typedef typename context_type::get_value_type type; |
134 | }; |
135 | |
136 | template <typename Env> |
137 | typename result<Env>::type |
138 | eval(Env const& env) const |
139 | { |
140 | return fusion::at_c<4>(env.args()).get_value(); |
141 | } |
142 | }; |
143 | |
144 | /////////////////////////////////////////////////////////////////////////// |
145 | // The value_setter is a Phoenix actor used to change the name of the |
146 | // current lexer state by calling set_state_name() on the context (which |
147 | // is the 5th parameter to any lexer semantic actions). |
148 | // |
149 | // This Phoenix actor is invoked whenever the placeholder '_val' is used |
150 | // as a lvalue inside a lexer semantic action: |
151 | // |
152 | // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; |
153 | // this->self = identifier [ _val = "identifier" ]; |
154 | // |
155 | // The example shows how to change the token value after matching a token |
156 | // 'identifier'. |
157 | template <typename Actor> |
158 | struct value_setter |
159 | { |
160 | typedef mpl::true_ no_nullary; |
161 | |
162 | template <typename Env> |
163 | struct result |
164 | { |
165 | typedef void type; |
166 | }; |
167 | |
168 | template <typename Env> |
169 | void eval(Env const& env) const |
170 | { |
171 | fusion::at_c<4>(env.args()).set_value(actor_.eval(env)); |
172 | } |
173 | |
174 | value_setter(Actor const& actor) |
175 | : actor_(actor) {} |
176 | |
177 | Actor actor_; |
178 | }; |
179 | |
180 | /////////////////////////////////////////////////////////////////////////// |
181 | // The eoi_getter is used to create the _eoi placeholder, which is a |
182 | // Phoenix actor used to access the end of input iterator pointing to the |
183 | // end of the underlying input sequence. |
184 | // |
185 | // This actor is invoked whenever the placeholder '_eoi' is used in a |
186 | // lexer semantic action: |
187 | // |
188 | // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; |
189 | // this->self = identifier |
190 | // [ std::cout << construct_<std::string>(_end, _eoi) ]; |
191 | // |
192 | // The example shows how to use _eoi to print all remaining input after |
193 | // matching a token 'identifier'. |
194 | struct eoi_getter |
195 | { |
196 | typedef mpl::true_ no_nullary; |
197 | |
198 | template <typename Env> |
199 | struct result |
200 | { |
201 | typedef |
202 | typename remove_reference< |
203 | typename remove_const< |
204 | typename mpl::at_c<typename Env::args_type, 4>::type |
205 | >::type |
206 | >::type |
207 | context_type; |
208 | |
209 | typedef typename context_type::base_iterator_type const& type; |
210 | }; |
211 | |
212 | template <typename Env> |
213 | typename result<Env>::type |
214 | eval(Env const& env) const |
215 | { |
216 | return fusion::at_c<4>(env.args()).get_eoi(); |
217 | } |
218 | }; |
219 | |
220 | /////////////////////////////////////////////////////////////////////////// |
221 | // '_start' and '_end' may be used to access the start and the end of |
222 | // the matched sequence of the current token |
223 | typedef phoenix::arg_names::_1_type _start_type; |
224 | typedef phoenix::arg_names::_2_type _end_type; |
225 | #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS |
226 | _start_type const _start = _start_type(); |
227 | _end_type const _end = _end_type(); |
228 | #endif |
229 | |
230 | // We are reusing the placeholder '_pass' to access and change the pass |
231 | // status of the current match (see support/argument.hpp for its |
232 | // definition). |
233 | // typedef phoenix::arg_names::_3_type _pass_type; |
234 | using boost::spirit::_pass_type; |
235 | #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS |
236 | using boost::spirit::_pass; |
237 | #endif |
238 | |
239 | // '_tokenid' may be used to access and change the tokenid of the current |
240 | // token |
241 | typedef phoenix::arg_names::_4_type _tokenid_type; |
242 | #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS |
243 | _tokenid_type const _tokenid = _tokenid_type(); |
244 | #endif |
245 | |
246 | typedef phoenix::actor<value_context> _val_type; |
247 | typedef phoenix::actor<state_context> _state_type; |
248 | typedef phoenix::actor<eoi_getter> _eoi_type; |
249 | #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS |
250 | // '_val' may be used to access and change the token value of the current |
251 | // token |
252 | _val_type const _val = _val_type(); |
253 | // _state may be used to access and change the name of the current lexer |
254 | // state |
255 | _state_type const _state = _state_type(); |
256 | // '_eoi' may be used to access the end of input iterator of the input |
257 | // stream used by the lexer to match tokens from |
258 | _eoi_type const _eoi = _eoi_type(); |
259 | #endif |
260 | }}} |
261 | |
262 | |
263 | #undef SPIRIT_DECLARE_ARG |
264 | #endif |
265 | |
266 | |