dedent_handling_phoenix.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright (c) 2009 Carl Barron
  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 <iostream>
  6. #include <sstream>
  7. #include <boost/detail/lightweight_test.hpp>
  8. #include <boost/spirit/include/lex.hpp>
  9. #include <boost/spirit/include/lex_lexertl.hpp>
  10. #include <boost/spirit/include/phoenix_core.hpp>
  11. #include <boost/spirit/include/phoenix_operator.hpp>
  12. #include <boost/spirit/include/phoenix_statement.hpp>
  13. namespace lex = boost::spirit::lex;
  14. namespace phoenix = boost::phoenix;
  15. ///////////////////////////////////////////////////////////////////////////////
  16. template <typename Lexer>
  17. struct multi_tokens : lex::lexer<Lexer>
  18. {
  19. int level;
  20. multi_tokens() : level(0)
  21. {
  22. using lex::_state;
  23. using lex::_start;
  24. using lex::_end;
  25. using lex::_pass;
  26. using lex::pass_flags;
  27. a = "A";
  28. b = "B";
  29. c = "C";
  30. this->self =
  31. a [ ++phoenix::ref(level) ]
  32. | b
  33. | c [
  34. _state = "in_dedenting",
  35. _end = _start,
  36. _pass = pass_flags::pass_ignore
  37. ]
  38. ;
  39. d = ".";
  40. this->self("in_dedenting") =
  41. d [
  42. if_(--phoenix::ref(level)) [
  43. _end = _start
  44. ]
  45. .else_ [
  46. _state = "INITIAL"
  47. ]
  48. ]
  49. ;
  50. }
  51. lex::token_def<> a, b, c, d;
  52. };
  53. struct dumper
  54. {
  55. typedef bool result_type;
  56. dumper(std::stringstream& strm) : strm(strm) {}
  57. template <typename Token>
  58. bool operator () (Token const &t)
  59. {
  60. strm << (char)(t.id() - lex::min_token_id + 'a');
  61. return true;
  62. }
  63. std::stringstream& strm;
  64. // silence MSVC warning C4512: assignment operator could not be generated
  65. BOOST_DELETED_FUNCTION(dumper& operator= (dumper const&));
  66. };
  67. ///////////////////////////////////////////////////////////////////////////////
  68. int main()
  69. {
  70. typedef lex::lexertl::token<std::string::iterator> token_type;
  71. typedef lex::lexertl::actor_lexer<token_type> base_lexer_type;
  72. typedef multi_tokens<base_lexer_type> lexer_type;
  73. std::string in("AAABBC");
  74. std::string::iterator first(in.begin());
  75. std::stringstream strm;
  76. lexer_type the_lexer;
  77. BOOST_TEST(lex::tokenize(first, in.end(), the_lexer, dumper(strm)));
  78. BOOST_TEST(strm.str() == "aaabbddd");
  79. return boost::report_errors();
  80. }