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