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