semantic_actions.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // Copyright (c) 2001-2011 Hartmut Kaiser
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #include <boost/detail/lightweight_test.hpp>
  6. #include <boost/config/warning_disable.hpp>
  7. #include <boost/spirit/include/lex_lexertl.hpp>
  8. namespace lex = boost::spirit::lex;
  9. typedef lex::lexertl::token<std::string::iterator> token_type;
  10. typedef lex::lexertl::actor_lexer<token_type> lexer_type;
  11. ///////////////////////////////////////////////////////////////////////////////
  12. static bool found_identifier_flag = false;
  13. ///////////////////////////////////////////////////////////////////////////////
  14. void found_identifier_sa0()
  15. {
  16. found_identifier_flag = true;
  17. }
  18. template <typename Lexer>
  19. struct lexer_sa0 : lex::lexer<Lexer>
  20. {
  21. lexer_sa0()
  22. {
  23. identifier = "[a-zA-Z][_a-zA-Z0-9]*";
  24. this->self += identifier [&found_identifier_sa0];
  25. }
  26. lex::token_def<> identifier;
  27. };
  28. ///////////////////////////////////////////////////////////////////////////////
  29. static std::string found_identifier_str;
  30. void found_identifier_sa2(std::string::iterator& start
  31. , std::string::iterator& end)
  32. {
  33. found_identifier_flag = true;
  34. found_identifier_str = std::string(start, end);
  35. }
  36. template <typename Lexer>
  37. struct lexer_sa2 : lex::lexer<Lexer>
  38. {
  39. lexer_sa2()
  40. {
  41. identifier = "[a-zA-Z][_a-zA-Z0-9]*";
  42. this->self += identifier [&found_identifier_sa2];
  43. }
  44. lex::token_def<> identifier;
  45. };
  46. ///////////////////////////////////////////////////////////////////////////////
  47. void found_identifier_sa3_normal(std::string::iterator& start
  48. , std::string::iterator& end, BOOST_SCOPED_ENUM(lex::pass_flags)& pass)
  49. {
  50. BOOST_TEST(pass == lex::pass_flags::pass_normal);
  51. found_identifier_flag = true;
  52. found_identifier_str = std::string(start, end);
  53. }
  54. template <typename Lexer>
  55. struct lexer_sa3_normal : lex::lexer<Lexer>
  56. {
  57. lexer_sa3_normal()
  58. {
  59. identifier = "[a-zA-Z][_a-zA-Z0-9]*";
  60. this->self += identifier [&found_identifier_sa3_normal];
  61. }
  62. lex::token_def<> identifier;
  63. };
  64. void found_identifier_sa3_fail(std::string::iterator&, std::string::iterator&
  65. , BOOST_SCOPED_ENUM(lex::pass_flags)& pass)
  66. {
  67. pass = lex::pass_flags::pass_fail;
  68. }
  69. template <typename Lexer>
  70. struct lexer_sa3_fail : lex::lexer<Lexer>
  71. {
  72. lexer_sa3_fail()
  73. {
  74. identifier = "[a-zA-Z][_a-zA-Z0-9]*";
  75. this->self += identifier [&found_identifier_sa3_fail];
  76. }
  77. lex::token_def<> identifier;
  78. };
  79. void found_identifier_sa3_ignore(std::string::iterator&, std::string::iterator&
  80. , BOOST_SCOPED_ENUM(lex::pass_flags)& pass)
  81. {
  82. pass = lex::pass_flags::pass_ignore;
  83. }
  84. template <typename Lexer>
  85. struct lexer_sa3_ignore : lex::lexer<Lexer>
  86. {
  87. lexer_sa3_ignore()
  88. {
  89. identifier = "[a-zA-Z][_a-zA-Z0-9]*";
  90. this->self += identifier [&found_identifier_sa3_ignore];
  91. }
  92. lex::token_def<> identifier;
  93. };
  94. ///////////////////////////////////////////////////////////////////////////////
  95. static std::size_t found_identifier_id = 0;
  96. void found_identifier_sa4(std::string::iterator& start
  97. , std::string::iterator& end, BOOST_SCOPED_ENUM(lex::pass_flags)& pass
  98. , std::size_t id)
  99. {
  100. BOOST_TEST(pass == lex::pass_flags::pass_normal);
  101. found_identifier_flag = true;
  102. found_identifier_str = std::string(start, end);
  103. found_identifier_id = id;
  104. }
  105. template <typename Lexer>
  106. struct lexer_sa4 : lex::lexer<Lexer>
  107. {
  108. lexer_sa4()
  109. {
  110. identifier = "[a-zA-Z][_a-zA-Z0-9]*";
  111. this->self += identifier [&found_identifier_sa4];
  112. }
  113. lex::token_def<> identifier;
  114. };
  115. void found_identifier_sa4_id(std::string::iterator& start
  116. , std::string::iterator& end, BOOST_SCOPED_ENUM(lex::pass_flags)& pass
  117. , std::size_t& id)
  118. {
  119. BOOST_TEST(pass == lex::pass_flags::pass_normal);
  120. found_identifier_flag = true;
  121. found_identifier_str = std::string(start, end);
  122. found_identifier_id = id;
  123. id = 1;
  124. }
  125. template <typename Lexer>
  126. struct lexer_sa4_id : lex::lexer<Lexer>
  127. {
  128. lexer_sa4_id()
  129. {
  130. identifier = "[a-zA-Z][_a-zA-Z0-9]*";
  131. this->self += identifier [&found_identifier_sa4_id];
  132. }
  133. lex::token_def<> identifier;
  134. };
  135. static std::size_t found_identifier_id2 = 0;
  136. bool identifier_token(token_type const& t)
  137. {
  138. found_identifier_id2 = t.id();
  139. return true;
  140. }
  141. ///////////////////////////////////////////////////////////////////////////////
  142. struct found_identifier_sa5
  143. {
  144. template <typename Context>
  145. void operator()(std::string::iterator& /*start*/
  146. , std::string::iterator& /*end*/, BOOST_SCOPED_ENUM(lex::pass_flags)& pass
  147. , std::size_t& /*id*/, Context& ctx)
  148. {
  149. BOOST_TEST(pass == lex::pass_flags::pass_normal);
  150. found_identifier_flag = true;
  151. found_identifier_str = std::string(ctx.get_value().begin(), ctx.get_value().end());
  152. }
  153. };
  154. template <typename Lexer>
  155. struct lexer_sa5 : lex::lexer<Lexer>
  156. {
  157. lexer_sa5()
  158. {
  159. identifier = "[a-zA-Z][_a-zA-Z0-9]*";
  160. this->self += identifier [found_identifier_sa5()];
  161. }
  162. lex::token_def<> identifier;
  163. };
  164. ///////////////////////////////////////////////////////////////////////////////
  165. int main()
  166. {
  167. std::string identifier ("id_1234");
  168. std::string::iterator first = identifier.begin();
  169. std::string::iterator last = identifier.end();
  170. // test semantic action taking no arguments
  171. found_identifier_flag = false;
  172. {
  173. lexer_sa0<lexer_type> sa0;
  174. BOOST_TEST(lex::tokenize(first, last, sa0));
  175. BOOST_TEST(first == last);
  176. BOOST_TEST(found_identifier_flag);
  177. }
  178. // test semantic action taking two arguments (iterator pair for matched
  179. // sequence)
  180. found_identifier_flag = false;
  181. found_identifier_str.clear();
  182. first = identifier.begin();
  183. {
  184. lexer_sa2<lexer_type> sa2;
  185. BOOST_TEST(lex::tokenize(first, last, sa2));
  186. BOOST_TEST(first == last);
  187. BOOST_TEST(found_identifier_flag);
  188. BOOST_TEST(found_identifier_str == identifier);
  189. }
  190. // test semantic action taking three arguments (iterator pair for matched
  191. // sequence and pass_flags) - pass_flags::pass_normal
  192. found_identifier_flag = false;
  193. found_identifier_str.clear();
  194. first = identifier.begin();
  195. {
  196. lexer_sa3_normal<lexer_type> sa3;
  197. BOOST_TEST(lex::tokenize(first, last, sa3));
  198. BOOST_TEST(first == last);
  199. BOOST_TEST(found_identifier_flag);
  200. BOOST_TEST(found_identifier_str == identifier);
  201. }
  202. // test semantic action taking three arguments (iterator pair for matched
  203. // sequence and pass_flags) - pass_flags::pass_fail
  204. first = identifier.begin();
  205. {
  206. lexer_sa3_fail<lexer_type> sa3;
  207. BOOST_TEST(!lex::tokenize(first, last, sa3));
  208. BOOST_TEST(first != last);
  209. }
  210. // test semantic action taking three arguments (iterator pair for matched
  211. // sequence and pass_flags) - pass_flags::pass_ignore
  212. first = identifier.begin();
  213. {
  214. lexer_sa3_ignore<lexer_type> sa3;
  215. BOOST_TEST(lex::tokenize(first, last, sa3));
  216. BOOST_TEST(first == last);
  217. }
  218. // test semantic action taking four arguments (iterator pair for matched
  219. // sequence and pass_flags, and token id)
  220. found_identifier_flag = false;
  221. found_identifier_str.clear();
  222. first = identifier.begin();
  223. found_identifier_id = 0;
  224. {
  225. lexer_sa4<lexer_type> sa4;
  226. BOOST_TEST(lex::tokenize(first, last, sa4));
  227. BOOST_TEST(first == last);
  228. BOOST_TEST(found_identifier_flag);
  229. BOOST_TEST(found_identifier_str == identifier);
  230. BOOST_TEST(found_identifier_id == lex::min_token_id);
  231. }
  232. found_identifier_flag = false;
  233. found_identifier_str.clear();
  234. first = identifier.begin();
  235. found_identifier_id = 0;
  236. found_identifier_id2 = 0;
  237. {
  238. lexer_sa4_id<lexer_type> sa4;
  239. BOOST_TEST(lex::tokenize(first, last, sa4, identifier_token));
  240. BOOST_TEST(first == last);
  241. BOOST_TEST(found_identifier_flag);
  242. BOOST_TEST(found_identifier_str == identifier);
  243. BOOST_TEST(found_identifier_id == lex::min_token_id);
  244. BOOST_TEST(found_identifier_id2 == 1);
  245. }
  246. // test semantic action taking four arguments (iterator pair for matched
  247. // sequence and pass_flags, token id, and context)
  248. found_identifier_flag = false;
  249. found_identifier_str.clear();
  250. first = identifier.begin();
  251. found_identifier_id = 0;
  252. found_identifier_id2 = 0;
  253. {
  254. lexer_sa5<lexer_type> sa5;
  255. BOOST_TEST(lex::tokenize(first, last, sa5));
  256. BOOST_TEST(first == last);
  257. BOOST_TEST(found_identifier_flag);
  258. BOOST_TEST(found_identifier_str == identifier);
  259. }
  260. return boost::report_errors();
  261. }