argument.hpp 13 KB

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