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_core.hpp> 13 #include <boost/spirit/include/phoenix_operator.hpp> 14 #include <boost/spirit/include/phoenix_statement.hpp> 15 16 namespace lex = boost::spirit::lex; 17 namespace phoenix = boost::phoenix; 18 19 /////////////////////////////////////////////////////////////////////////////// 20 template <typename Lexer> 21 struct multi_tokens : lex::lexer<Lexer> 22 { 23 int level; 24 multi_tokensmulti_tokens25 multi_tokens() : level(0) 26 { 27 using lex::_state; 28 using lex::_start; 29 using lex::_end; 30 using lex::_pass; 31 using lex::pass_flags; 32 33 a = "A"; 34 b = "B"; 35 c = "C"; 36 this->self = 37 a [ ++phoenix::ref(level) ] 38 | b 39 | c [( 40 _state = "in_dedenting", 41 _end = _start, 42 _pass = pass_flags::pass_ignore 43 )] 44 ; 45 46 d = "."; 47 this->self("in_dedenting") = 48 d [ 49 if_(--phoenix::ref(level)) [ 50 _end = _start 51 ] 52 .else_ [ 53 _state = "INITIAL" 54 ] 55 ] 56 ; 57 } 58 59 lex::token_def<> a, b, c, d; 60 }; 61 62 struct dumper 63 { 64 typedef bool result_type; 65 dumperdumper66 dumper(std::stringstream& strm) : strm(strm) {} 67 68 template <typename Token> operator ()dumper69 bool operator () (Token const &t) 70 { 71 strm << (char)(t.id() - lex::min_token_id + 'a'); 72 return true; 73 } 74 75 std::stringstream& strm; 76 77 // silence MSVC warning C4512: assignment operator could not be generated 78 BOOST_DELETED_FUNCTION(dumper& operator= (dumper const&)); 79 }; 80 81 /////////////////////////////////////////////////////////////////////////////// main()82int main() 83 { 84 typedef lex::lexertl::token<std::string::iterator> token_type; 85 typedef lex::lexertl::actor_lexer<token_type> base_lexer_type; 86 typedef multi_tokens<base_lexer_type> lexer_type; 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