| // Copyright (c) 2009 Carl Barron |
| // |
| // Distributed under the Boost Software License, Version 1.0. (See accompanying |
| // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| |
| #include <iostream> |
| #include <sstream> |
| |
| #include <boost/detail/lightweight_test.hpp> |
| #include <boost/spirit/include/lex.hpp> |
| #include <boost/spirit/include/lex_lexertl.hpp> |
| #include <boost/spirit/include/phoenix.hpp> |
| |
| namespace lex = boost::spirit::lex; |
| namespace phoenix = boost::phoenix; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| template <typename Lexer> |
| struct multi_tokens : lex::lexer<Lexer> |
| { |
| int level; |
| |
| multi_tokens() : level(0) |
| { |
| using lex::_state; |
| using lex::_start; |
| using lex::_end; |
| using lex::_pass; |
| using lex::pass_flags; |
| |
| a = "A"; |
| b = "B"; |
| c = "C"; |
| this->self = |
| a [ ++phoenix::ref(level) ] |
| | b |
| | c [ |
| _state = "in_dedenting", |
| _end = _start, |
| _pass = pass_flags::pass_ignore |
| ] |
| ; |
| |
| d = "."; |
| this->self("in_dedenting") = |
| d [ |
| if_(--phoenix::ref(level)) [ |
| _end = _start |
| ] |
| .else_ [ |
| _state = "INITIAL" |
| ] |
| ] |
| ; |
| } |
| |
| lex::token_def<> a, b, c, d; |
| }; |
| |
| struct dumper |
| { |
| typedef bool result_type; |
| |
| dumper(std::stringstream& strm) : strm(strm) {} |
| |
| template <typename Token> |
| bool operator () (Token const &t) |
| { |
| strm << (char)(t.id() - lex::min_token_id + 'a'); |
| return true; |
| } |
| |
| std::stringstream& strm; |
| |
| private: |
| // silence MSVC warning C4512: assignment operator could not be generated |
| dumper& operator= (dumper const&); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| int main() |
| { |
| typedef lex::lexertl::token<std::string::iterator> token_type; |
| typedef lex::lexertl::actor_lexer<token_type> base_lexer_type; |
| typedef multi_tokens<base_lexer_type> lexer_type; |
| typedef lexer_type::iterator_type iterator; |
| |
| std::string in("AAABBC"); |
| std::string::iterator first(in.begin()); |
| std::stringstream strm; |
| |
| lexer_type the_lexer; |
| BOOST_TEST(lex::tokenize(first, in.end(), the_lexer, dumper(strm))); |
| BOOST_TEST(strm.str() == "aaabbddd"); |
| |
| return boost::report_errors(); |
| } |
| |