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