regex_convert.cpp

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

CPP
178
字号
/*=============================================================================    Copyright (c) 2002-2003 Martin Wille    http://spirit.sourceforge.net/    Use, modification and distribution is subject to 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)=============================================================================*////////////////////////////////////////////////////////////////////////////////// vim:ts=4:sw=4:et////  Demonstrate regular expression parsers for match based text conversion////  This sample requires an installed version of the boost regex library//  (http://www.boost.org) The sample was tested with boost V1.29.0////  Note: - there is no error handling in this example//        - this program isn't particularly useful////  This example shows one way build a kind of filter program.//  It reads input from std::cin and uses a grammar and actions//  to print out a modified version of the input.////  [ Martin Wille, 10/18/2002 ]/////////////////////////////////////////////////////////////////////////////////#include <string>#include <iostream>#include <streambuf>#include <sstream>#include <deque>#include <iterator>#include <boost/function.hpp>#include <boost/spirit/include/classic_core.hpp>///////////////////////////////////////////////////////////////////////////////////  The following header must be included, if regular expression support is//  required for Spirit.////  The BOOST_SPIRIT_NO_REGEX_LIB PP constant should be defined, if you're using the//  Boost.Regex library from one translation unit only. Otherwise you have to//  link with the Boost.Regex library as defined in the related documentation//  (see. http://www.boost.org)./////////////////////////////////////////////////////////////////////////////////#define BOOST_SPIRIT_NO_REGEX_LIB#include <boost/spirit/include/classic_regex.hpp>using namespace BOOST_SPIRIT_CLASSIC_NS;using namespace std;namespace {    long triple(long val)    {        return 3*val;    }    ///////////////////////////////////////////////////////////////////////////    //    // actions    //    struct emit_constant    {        emit_constant(string const &text)            : msg(text)        {}        template<typename Iterator>        void operator()(Iterator b, Iterator e) const        {            cout.rdbuf()->sputn(msg.data(), msg.size());        }    private:        string msg;    };    void    copy_unmodified(char letter)    {        cout.rdbuf()->sputc(letter);    }    struct emit_modified_subscript    {        emit_modified_subscript(boost::function<long (long)> const &f)            : modifier(f)        {}        template<typename Iterator>        void operator()(Iterator b, Iterator e) const        {            string tmp(b+1,e-1);            long val = strtol(tmp.c_str(),0, 0);            ostringstream os;            os << modifier(val);            tmp = os.str();            cout.rdbuf()->sputc('[');            cout.rdbuf()->sputn(tmp.c_str(), tmp.size());            cout.rdbuf()->sputc(']');        }    private:        boost::function<long (long)> modifier;    };}/////////////////////////////////////////////////////////////////////////////////  The grammar 'conversion_grammar' serves as a working horse for match based//  text conversion. It does the following:////      - converts the word "class" into the word "struct"//      - multiplies any integer number enclosed in square brackets with 3//      - any other input is simply copied to the outputstruct conversion_grammar     : grammar<conversion_grammar>{    template<class ScannerT>    struct definition    {        typedef ScannerT scanner_t;        definition(conversion_grammar const &)        {            static const char expr[] = "\\[\\d+\\]";            first = (                /////////////////////////////////////////////////////////////                // note that "fallback" is the last alternative here !                top  = *(class2struct || subscript || fallback),                /////////////////////////////////////////////////////////////                // replace any occurrance of "class" by "struct"                class2struct = str_p("class") [emit_constant("struct")],                /////////////////////////////////////////////////////////////                // if the input maches "[some_number]"                // "some_number" is multiplied by 3 before printing                subscript = regex_p(expr) [emit_modified_subscript(&triple)],                /////////////////////////////////////////////////////////////                // if nothing else can be done with the input                // then it will be printed without modifications                fallback = anychar_p [&copy_unmodified]            );        }        rule<scanner_t> const & start() { return first; }    private:        subrule<0> top;        subrule<1> class2struct;        subrule<2> subscript;        subrule<3> fallback;        rule<scanner_t> first;    };};intmain(){    //  this would print "struct foo {}; foo bar[9];":    //  parse("class foo {}; foo bar[3];", conversion_grammar());    // Note: the regular expression parser contained in the    //       grammar requires a bidirectional iterator. Therefore,    //       we cannot use sdt::istreambuf_iterator as one would    //       do with other Spirit parsers.    istreambuf_iterator<char> input_iterator(cin);    std::deque<char> input(input_iterator, istreambuf_iterator<char>());    parse(input.begin(), input.end(), conversion_grammar());    return 0;}

⌨️ 快捷键说明

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