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