lexer_state_switcher.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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/mpl/print.hpp>
  6. #include <boost/detail/lightweight_test.hpp>
  7. #include <boost/spirit/include/phoenix_object.hpp>
  8. #include <boost/spirit/include/phoenix_operator.hpp>
  9. #include <boost/spirit/include/lex_lexertl.hpp>
  10. ///////////////////////////////////////////////////////////////////////////////
  11. // Token definition
  12. ///////////////////////////////////////////////////////////////////////////////
  13. template <typename Lexer>
  14. struct switch_state_tokens : boost::spirit::lex::lexer<Lexer>
  15. {
  16. // define tokens and associate them with the lexer
  17. switch_state_tokens()
  18. {
  19. namespace phoenix = boost::phoenix;
  20. using boost::spirit::lex::_state;
  21. identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
  22. this->self = identifier [ phoenix::ref(state_) = _state ];
  23. integer = "[0-9]+";
  24. this->self("INT") = integer [ _state = "INITIAL" ];
  25. }
  26. std::string state_;
  27. boost::spirit::lex::token_def<> identifier, integer;
  28. };
  29. ///////////////////////////////////////////////////////////////////////////////
  30. int main()
  31. {
  32. using namespace boost::spirit;
  33. using namespace boost::spirit::lex;
  34. typedef std::string::iterator base_iterator_type;
  35. typedef boost::spirit::lex::lexertl::token<base_iterator_type> token_type;
  36. typedef boost::spirit::lex::lexertl::actor_lexer<token_type> lexer_type;
  37. {
  38. switch_state_tokens<lexer_type> lex;
  39. {
  40. // verify whether using _state as an rvalue works
  41. std::string input("abc123");
  42. base_iterator_type first = input.begin();
  43. BOOST_TEST(boost::spirit::lex::tokenize(first, input.end(), lex) &&
  44. lex.state_ == "INITIAL");
  45. }
  46. {
  47. // verify whether using _state as an lvalue works
  48. std::string input("123abc123");
  49. base_iterator_type first = input.begin();
  50. BOOST_TEST(boost::spirit::lex::tokenize(first, input.end(), lex, "INT") &&
  51. lex.state_ == "INITIAL");
  52. }
  53. }
  54. return boost::report_errors();
  55. }