]>
Commit | Line | Data |
---|---|---|
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(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_(--phoenix::ref(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 |