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 [©_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 + -
显示快捷键?