// Copyright (c) 2001-2010 Hartmut Kaiser // // 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) // The purpose of this example is to show, how it is possible to use a lexer // token definition for two purposes: // // . To generate C++ code implementing a static lexical analyzer allowing // to recognize all defined tokens // . To integrate the generated C++ lexer into the /Spirit/ framework. // // #define BOOST_SPIRIT_DEBUG // #define BOOST_SPIRIT_LEXERTL_DEBUG #include #include #include #include #include "../example.hpp" #include "word_count_lexer_tokens.hpp" // token definition #include "word_count_lexer_static.hpp" // generated tokenizer using namespace boost::spirit; /////////////////////////////////////////////////////////////////////////////// //[wcl_static_main int main(int argc, char* argv[]) { // read input from the given file std::string str (read_from_file(1 == argc ? "word_count.input" : argv[1])); // Specifying 'omit' as the token attribute type generates a token class // notholding any token attribute at all (not even the iterator_range of the // matched input sequence), therefor optimizing the token, the lexer, and // possibly the parser implementation as much as possible. // // Specifying mpl::false_ as the 3rd template parameter generates a token // type and an iterator, both holding no lexer state, allowing for even more // aggressive optimizations. // // As a result the token instances contain the token ids as the only data // member. typedef lex::lexertl::token token_type; // Define the lexer type to be used as the base class for our token // definition. // // This is the only place where the code is different from an equivalent // dynamic lexical analyzer. We use the `lexertl::static_lexer<>` instead of // the `lexertl::lexer<>` as the base class for our token defintion type. // // As we specified the suffix "wcl" while generating the static tables we // need to pass the type lexertl::static_::lexer_wcl as the second template // parameter below (see word_count_lexer_generate.cpp). typedef lex::lexertl::static_actor_lexer< token_type, lex::lexertl::static_::lexer_wcl > lexer_type; // create the lexer object instance needed to invoke the lexical analysis word_count_lexer_tokens word_count_lexer; // tokenize the given string, all generated tokens are discarded char const* first = str.c_str(); char const* last = &first[str.size()]; bool r = lex::tokenize(first, last, word_count_lexer); if (r) { std::cout << "lines: " << word_count_lexer.l << ", words: " << word_count_lexer.w << ", characters: " << word_count_lexer.c << "\n"; } else { std::string rest(first, last); std::cout << "Lexical analysis failed\n" << "stopped at: \"" << rest << "\"\n"; } return 0; } //]