test_actions.cpp

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

CPP
244
字号
///////////////////////////////////////////////////////////////////////////////// test_actions.cpp////  Copyright 2008 Eric Niebler. 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)//#define BOOST_XPRESSIVE_BETTER_ERRORS#include <map>#include <list>#include <stack>#include <numeric>#include <boost/version.hpp>#include <boost/xpressive/xpressive_static.hpp>#include <boost/xpressive/regex_actions.hpp>#include <boost/test/unit_test.hpp>namespace xp = boost::xpressive;///////////////////////////////////////////////////////////////////////////////// test1//  simple action which builds a stringvoid test1(){    using namespace boost::xpressive;    std::string result;    std::string str("foo bar baz foo bar baz");    sregex rx = (+_w)[ xp::ref(result) += _ ] >> *(' ' >> (+_w)[ xp::ref(result) += ',' + _ ]);    if(!regex_match(str, rx))    {        BOOST_ERROR("oops");    }    else    {        BOOST_CHECK_EQUAL(result, "foo,bar,baz,foo,bar,baz");    }}///////////////////////////////////////////////////////////////////////////////// test2//  test backtracking over actionsvoid test2(){    using namespace boost::xpressive;    std::string result;    std::string str("foo bar baz foo bar baz");    sregex rx = (+_w)[ xp::ref(result) += _ ] >> *(' ' >> (+_w)[ xp::ref(result) += ',' + _ ]) >> repeat<4>(_);    if(!regex_match(str, rx))    {        BOOST_ERROR("oops");    }    else    {        BOOST_CHECK_EQUAL(result, "foo,bar,baz,foo,bar");    }}///////////////////////////////////////////////////////////////////////////////// test3//  cast string to int, push back into list, use alternate ->* syntaxvoid test3(){    using namespace boost::xpressive;    std::list<int> result;    std::string str("1 23 456 7890");#if BOOST_VERSION >= 103500    sregex rx = (+_d)[ xp::ref(result)->*push_back( as<int>(_) ) ]        >> *(' ' >> (+_d)[ xp::ref(result)->*push_back( as<int>(_) ) ]);#else    sregex rx = (+_d)[ push_back(xp::ref(result), as<int>(_) ) ]        >> *(' ' >> (+_d)[ push_back(xp::ref(result), as<int>(_) ) ]);#endif    if(!regex_match(str, rx))    {        BOOST_ERROR("oops");    }    else    {        BOOST_REQUIRE_EQUAL(result.size(), 4u);        BOOST_CHECK_EQUAL(*result.begin(), 1);        BOOST_CHECK_EQUAL(*++result.begin(), 23);        BOOST_CHECK_EQUAL(*++++result.begin(), 456);        BOOST_CHECK_EQUAL(*++++++result.begin(), 7890);    }}///////////////////////////////////////////////////////////////////////////////// test4//  build a map of strings to integersvoid test4(){    using namespace boost::xpressive;    std::map<std::string, int> result;    std::string str("aaa=>1 bbb=>23 ccc=>456");    sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )[ xp::ref(result)[s1] = as<int>(s2) ];    sregex rx = pair >> *(+_s >> pair);    if(!regex_match(str, rx))    {        BOOST_ERROR("oops");    }    else    {        BOOST_REQUIRE_EQUAL(result.size(), 3u);        BOOST_CHECK_EQUAL(result["aaa"], 1);        BOOST_CHECK_EQUAL(result["bbb"], 23);        BOOST_CHECK_EQUAL(result["ccc"], 456);    }}///////////////////////////////////////////////////////////////////////////////// test4_aux//  build a map of strings to integers, with a late-bound action argument.void test4_aux(){    using namespace boost::xpressive;    placeholder< std::map<std::string, int> > const _map = {{}};    sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )[ _map[s1] = as<int>(s2) ];    sregex rx = pair >> *(+_s >> pair);    std::string str("aaa=>1 bbb=>23 ccc=>456");    smatch what;    std::map<std::string, int> result;    what.let(_map = result); // bind the argument!    BOOST_REQUIRE(regex_match(str, what, rx));    BOOST_REQUIRE_EQUAL(result.size(), 3u);    BOOST_CHECK_EQUAL(result["aaa"], 1);    BOOST_CHECK_EQUAL(result["bbb"], 23);    BOOST_CHECK_EQUAL(result["ccc"], 456);    // Try the same test with regex_iterator    result.clear();    sregex_iterator it(str.begin(), str.end(), pair, let(_map=result)), end;    BOOST_REQUIRE_EQUAL(3, std::distance(it, end));    BOOST_REQUIRE_EQUAL(result.size(), 3u);    BOOST_CHECK_EQUAL(result["aaa"], 1);    BOOST_CHECK_EQUAL(result["bbb"], 23);    BOOST_CHECK_EQUAL(result["ccc"], 456);    // Try the same test with regex_token_iterator    result.clear();    sregex_token_iterator it2(str.begin(), str.end(), pair, (s1,s2), let(_map=result)), end2;    BOOST_REQUIRE_EQUAL(6, std::distance(it2, end2));    BOOST_REQUIRE_EQUAL(result.size(), 3u);    BOOST_CHECK_EQUAL(result["aaa"], 1);    BOOST_CHECK_EQUAL(result["bbb"], 23);    BOOST_CHECK_EQUAL(result["ccc"], 456);}///////////////////////////////////////////////////////////////////////////////// test5//  calculator that calculates. This is just silly, but hey.void test5(){    using namespace boost::xpressive;    // test for "local" variables.    local<int> left, right;    // test for reference<> to an existing variable    std::stack<int> stack_;    reference<std::stack<int> > stack(stack_);    std::string str("4+5*(3-1)");    sregex group, factor, term, expression;    group       = '(' >> by_ref(expression) >> ')';    factor      = (+_d)[ push(stack, as<int>(_)) ] | group;    term        = factor >> *(                                ('*' >> factor)                                    [ right = top(stack)                                    , pop(stack)                                    , left = top(stack)                                    , pop(stack)                                    , push(stack, left * right)                                    ]                              | ('/' >> factor)                                    [ right = top(stack)                                    , pop(stack)                                    , left = top(stack)                                    , pop(stack)                                    , push(stack, left / right)                                    ]                             );    expression  = term >> *(                                ('+' >> term)                                    [ right = top(stack)                                    , pop(stack)                                    , left = top(stack)                                    , pop(stack)                                    , push(stack, left + right)                                    ]                              | ('-' >> term)                                    [ right = top(stack)                                    , pop(stack)                                    , left = top(stack)                                    , pop(stack)                                    , push(stack, left - right)                                    ]                             );    if(!regex_match(str, expression))    {        BOOST_ERROR("oops");    }    else    {        BOOST_REQUIRE_EQUAL(stack_.size(), 1u);        BOOST_CHECK_EQUAL(stack_.top(), 14);        BOOST_REQUIRE_EQUAL(stack.get().size(), 1u);        BOOST_CHECK_EQUAL(stack.get().top(), 14);    }}using namespace boost::unit_test;///////////////////////////////////////////////////////////////////////////////// init_unit_test_suite//test_suite* init_unit_test_suite( int argc, char* argv[] ){    test_suite *test = BOOST_TEST_SUITE("test_actions");    test->add(BOOST_TEST_CASE(&test1));    test->add(BOOST_TEST_CASE(&test2));    test->add(BOOST_TEST_CASE(&test3));    test->add(BOOST_TEST_CASE(&test4));    test->add(BOOST_TEST_CASE(&test4_aux));    test->add(BOOST_TEST_CASE(&test5));    return test;}

⌨️ 快捷键说明

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