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