word_count_lexer.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 135 行

CPP
135
字号
//  Copyright (c) 2001-2008 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)//  This example is the equivalent to the following lex program:/*//[wcl_flex_version    %{        int c = 0, w = 0, l = 0;    %}    %%    [^ \t\n]+  { ++w; c += yyleng; }    \n         { ++c; ++l; }    .          { ++c; }    %%    main()    {        yylex();        printf("%d %d %d\n", l, w, c);    }//]*///  Its purpose is to do the word count function of the wc command in UNIX. It //  prints the number of lines, words and characters in a file. ////  This examples shows how to use semantic actions associated with token //  definitions to directly attach actions to tokens. These get executed //  whenever the corresponding token got matched in the input sequence. Note,//  how this example implements all functionality directly in the lexer //  definition without any need for a parser.// #define BOOST_SPIRIT_LEXERTL_DEBUG#include <boost/config/warning_disable.hpp>//[wcl_includes#include <boost/spirit/include/support_argument.hpp>#include <boost/spirit/include/lex_lexer_lexertl.hpp>#include <boost/spirit/include/phoenix_operator.hpp>#include <boost/spirit/include/phoenix_statement.hpp>#include <boost/spirit/include/phoenix_algorithm.hpp>#include <boost/spirit/include/phoenix_core.hpp>//]#include <iostream>#include <string>#include "example.hpp"//[wcl_namespacesusing namespace boost::spirit;using namespace boost::spirit::lex;//]/////////////////////////////////////////////////////////////////////////////////  Token definition: We use the lexertl based lexer engine as the underlying //                    lexer type.////  Note, the token definition type is derived from the 'lexertl_actor_lexer'//  template, which is a necessary to being able to use lexer semantic actions./////////////////////////////////////////////////////////////////////////////////[wcl_token_definitiontemplate <typename Lexer>struct word_count_tokens : lexer_def<Lexer>{    word_count_tokens()      : c(0), w(0), l(0),        word("[^ \t\n]+"), eol("\n"), any(".")  // define tokens    {}        template <typename Self>    void def (Self& self)    {        using boost::phoenix::ref;        using boost::phoenix::distance;        using boost::spirit::arg_names::_1;        // associate tokens with the lexer        self =  word  [++ref(w), ref(c) += distance(_1)]            |   eol   [++ref(c), ++ref(l)]             |   any   [++ref(c)]            ;    }        std::size_t c, w, l;    token_def<> word, eol, any;};//]/////////////////////////////////////////////////////////////////////////////////[wcl_mainint 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 'omitted' as the token value type generates a token class not    // holding any token value 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 lexertl_token<char const*, omitted, boost::mpl::false_> token_type;    // lexer type    typedef lexertl_actor_lexer<token_type> lexer_type;        // create the lexer object instance needed to invoke the lexical analysis     word_count_tokens<lexer_type> 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 = tokenize(first, last, make_lexer(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;}//]

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?