argument.hpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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/home/support/string_traits.hpp>
  14. #include <boost/spirit/home/lex/argument_phoenix.hpp>
  15. #include <boost/fusion/include/at.hpp>
  16. #include <boost/mpl/at.hpp>
  17. #include <boost/mpl/bool.hpp>
  18. #include <boost/phoenix/core/actor.hpp>
  19. #include <boost/phoenix/core/argument.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. fusion::at_c<4>(env.args()).set_state_name(
  87. traits::get_c_string(actor_.eval(env)));
  88. }
  89. state_setter(Actor const& actor)
  90. : actor_(actor) {}
  91. Actor actor_;
  92. };
  93. ///////////////////////////////////////////////////////////////////////////
  94. // The value_getter is used to create the _val placeholder, which is a
  95. // Phoenix actor used to access the value of the current token.
  96. //
  97. // This Phoenix actor is invoked whenever the placeholder '_val' is used
  98. // as a rvalue inside a lexer semantic action:
  99. //
  100. // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
  101. // this->self = identifier [ std::cout << _val ];
  102. //
  103. // The example shows how to use _val to print the identifier name (which
  104. // is the initial token value).
  105. struct value_getter
  106. {
  107. typedef mpl::true_ no_nullary;
  108. template <typename Env>
  109. struct result
  110. {
  111. typedef
  112. typename remove_reference<
  113. typename remove_const<
  114. typename mpl::at_c<typename Env::args_type, 4>::type
  115. >::type
  116. >::type
  117. context_type;
  118. typedef typename context_type::get_value_type type;
  119. };
  120. template <typename Env>
  121. typename result<Env>::type
  122. eval(Env const& env) const
  123. {
  124. return fusion::at_c<4>(env.args()).get_value();
  125. }
  126. };
  127. ///////////////////////////////////////////////////////////////////////////
  128. // The value_setter is a Phoenix actor used to change the name of the
  129. // current lexer state by calling set_state_name() on the context (which
  130. // is the 5th parameter to any lexer semantic actions).
  131. //
  132. // This Phoenix actor is invoked whenever the placeholder '_val' is used
  133. // as a lvalue inside a lexer semantic action:
  134. //
  135. // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
  136. // this->self = identifier [ _val = "identifier" ];
  137. //
  138. // The example shows how to change the token value after matching a token
  139. // 'identifier'.
  140. template <typename Actor>
  141. struct value_setter
  142. {
  143. typedef mpl::true_ no_nullary;
  144. template <typename Env>
  145. struct result
  146. {
  147. typedef void type;
  148. };
  149. template <typename Env>
  150. void eval(Env const& env) const
  151. {
  152. fusion::at_c<4>(env.args()).set_value(actor_.eval(env));
  153. }
  154. value_setter(Actor const& actor)
  155. : actor_(actor) {}
  156. Actor actor_;
  157. };
  158. ///////////////////////////////////////////////////////////////////////////
  159. // The eoi_getter is used to create the _eoi placeholder, which is a
  160. // Phoenix actor used to access the end of input iterator pointing to the
  161. // end of the underlying input sequence.
  162. //
  163. // This actor is invoked whenever the placeholder '_eoi' is used in a
  164. // lexer semantic action:
  165. //
  166. // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
  167. // this->self = identifier
  168. // [ std::cout << construct_<std::string>(_end, _eoi) ];
  169. //
  170. // The example shows how to use _eoi to print all remaining input after
  171. // matching a token 'identifier'.
  172. struct eoi_getter
  173. {
  174. typedef mpl::true_ no_nullary;
  175. template <typename Env>
  176. struct result
  177. {
  178. typedef
  179. typename remove_reference<
  180. typename remove_const<
  181. typename mpl::at_c<typename Env::args_type, 4>::type
  182. >::type
  183. >::type
  184. context_type;
  185. typedef typename context_type::base_iterator_type const& type;
  186. };
  187. template <typename Env>
  188. typename result<Env>::type
  189. eval(Env const& env) const
  190. {
  191. return fusion::at_c<4>(env.args()).get_eoi();
  192. }
  193. };
  194. ///////////////////////////////////////////////////////////////////////////
  195. // '_start' and '_end' may be used to access the start and the end of
  196. // the matched sequence of the current token
  197. typedef phoenix::arg_names::_1_type _start_type;
  198. typedef phoenix::arg_names::_2_type _end_type;
  199. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  200. _start_type const _start = _start_type();
  201. _end_type const _end = _end_type();
  202. #endif
  203. // We are reusing the placeholder '_pass' to access and change the pass
  204. // status of the current match (see support/argument.hpp for its
  205. // definition).
  206. // typedef phoenix::arg_names::_3_type _pass_type;
  207. using boost::spirit::_pass_type;
  208. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  209. using boost::spirit::_pass;
  210. #endif
  211. // '_tokenid' may be used to access and change the tokenid of the current
  212. // token
  213. typedef phoenix::arg_names::_4_type _tokenid_type;
  214. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  215. _tokenid_type const _tokenid = _tokenid_type();
  216. #endif
  217. typedef phoenix::actor<value_context> _val_type;
  218. typedef phoenix::actor<state_context> _state_type;
  219. typedef phoenix::actor<eoi_getter> _eoi_type;
  220. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  221. // '_val' may be used to access and change the token value of the current
  222. // token
  223. _val_type const _val = _val_type();
  224. // _state may be used to access and change the name of the current lexer
  225. // state
  226. _state_type const _state = _state_type();
  227. // '_eoi' may be used to access the end of input iterator of the input
  228. // stream used by the lexer to match tokens from
  229. _eoi_type const _eoi = _eoi_type();
  230. #endif
  231. }}}
  232. #undef SPIRIT_DECLARE_ARG
  233. #endif