]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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/include/phoenix_core.hpp> | |
17 | #include <boost/spirit/include/phoenix_operator.hpp> | |
18 | #include <boost/spirit/home/support/string_traits.hpp> | |
19 | #include <boost/spirit/home/lex/argument_phoenix.hpp> | |
20 | #include <boost/fusion/include/at.hpp> | |
21 | #include <boost/mpl/at.hpp> | |
22 | #include <boost/mpl/bool.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 |