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
evalboost::spirit::lex::state_getter63         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>
evalboost::spirit::lex::state_setter94         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 
state_setterboost::spirit::lex::state_setter100         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
evalboost::spirit::lex::value_getter138         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>
evalboost::spirit::lex::value_setter169         void eval(Env const& env) const
170         {
171             fusion::at_c<4>(env.args()).set_value(actor_.eval(env));
172         }
173 
value_setterboost::spirit::lex::value_setter174         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
evalboost::spirit::lex::eoi_getter214         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