/////////////////////////////////////////////////////////////////////////////// // test_symbols.cpp // // Copyright 2008 David Jenkins. // 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) #include #include #include #include #include #include #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() namespace xp = boost::xpressive; /////////////////////////////////////////////////////////////////////////////// // test1 // simple action which builds a *translated* string void test1() { using namespace boost::xpressive; local result; std::string str("foo bar baz foo bar baz"); std::map map1; map1["foo"] = "1"; map1["bar"] = "2"; map1["baz"] = "3"; sregex rx = skip(_s) (+(a1=map1) [ result += if_else(length(result) > 0, ",", "") + a1 ] ); if(!regex_match(str, rx)) { BOOST_ERROR("oops"); } else { BOOST_CHECK_EQUAL(result.get(), "1,2,3,1,2,3"); } } /////////////////////////////////////////////////////////////////////////////// // test2 // find longest match in symbol table void test2() { using namespace boost::xpressive; local result; std::string str("foobarbazfoobazbazfoobazbar"); std::map map1; map1["foo"] = "1"; map1["bar"] = "2"; map1["baz"] = "3"; map1["foobaz"] = "4"; map1["foobazbaz"] = "5"; sregex rx = skip(_s) (+(a1=map1) [ result += if_else(length(result) > 0, ",", "") + a1 ] ); if(!regex_match(str, rx)) { BOOST_ERROR("oops"); } else { BOOST_CHECK_EQUAL(result.get(), "1,2,3,5,4,2"); } } /////////////////////////////////////////////////////////////////////////////// // test3 // *map* string to int, push back into list, use alternate ->* syntax void test3() { using namespace boost::xpressive; std::list result; std::string str("foo bar baz bop"); std::map map1; map1["foo"] = 1; map1["bar"] = 23; map1["baz"] = 456; map1["bop"] = 7890; #if BOOST_VERSION >= 103500 sregex rx = skip(_s) (+(a1=map1) [ xp::ref(result)->*push_back( a1 ) ] ); #else sregex rx = skip(_s) (+(a1=map1) [ push_back(xp::ref(result), a1 ) ] ); #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 // use two input maps to build an output map, with a late-bound action argument. void test4() { using namespace boost::xpressive; placeholder< std::map > const _map = {}; std::string str("aaa=>1 bbb=>2 ccc=>3"); std::map map1; map1["aaa"] = "foo"; map1["bbb"] = "bar"; map1["ccc"] = "baz"; std::map map2; map2["1"] = 1; map2["2"] = 23; map2["3"] = 456; sregex pair = ( (a1=map1) >> "=>" >> (a2= map2) )[ _map[a1] = a2 ]; sregex rx = pair >> *(+_s >> pair); smatch what; std::map result; what.let(_map = result); // bind the argument! if(!regex_match(str, what, rx)) { BOOST_ERROR("oops"); } else { BOOST_REQUIRE_EQUAL(result.size(), 3u); BOOST_CHECK_EQUAL(result["foo"], 1); BOOST_CHECK_EQUAL(result["bar"], 23); BOOST_CHECK_EQUAL(result["baz"], 456); } } /////////////////////////////////////////////////////////////////////////////// // test5 // test nine maps and attributes void test5() { using namespace boost::xpressive; local result(0); std::string str("abcdefghi"); std::map map1; std::map map2; std::map map3; std::map map4; std::map map5; std::map map6; std::map map7; std::map map8; std::map map9; map1["a"] = 1; map2["b"] = 2; map3["c"] = 3; map4["d"] = 4; map5["e"] = 5; map6["f"] = 6; map7["g"] = 7; map8["h"] = 8; map9["i"] = 9; sregex rx = (a1=map1)[ result += a1 ] >> (a2=map2)[ result += a2 ] >> (a3=map3)[ result += a3 ] >> (a4=map4)[ result += a4 ] >> (a5=map5)[ result += a5 ] >> (a6=map6)[ result += a6 ] >> (a7=map7)[ result += a7 ] >> (a8=map8)[ result += a8 ] >> (a9=map9)[ result += a9 ]; if(!regex_match(str, rx)) { BOOST_ERROR("oops"); } else { BOOST_CHECK_EQUAL(result.get(), 45); } } /////////////////////////////////////////////////////////////////////////////// // test6 // test case-sensitivity void test6() { using namespace boost::xpressive; local result; std::map map1; map1["a"] = "1"; map1["A"] = "2"; map1["b"] = "3"; map1["B"] = "4"; std::string str("a A b B a A b B"); sregex rx = skip(_s)( icase(a1= map1) [ result = a1 ] >> repeat<3>( (icase(a1= map1) [ result += ',' + a1 ]) ) >> repeat<4>( ((a1= map1) [ result += ',' + a1 ]) ) ); if(!regex_match(str, rx)) { BOOST_ERROR("oops"); } else { BOOST_CHECK_EQUAL(result.get(), "1,1,3,3,1,2,3,4"); } } /////////////////////////////////////////////////////////////////////////////// // test7 // test multiple mutually-exclusive maps and default attribute value void test7() { using namespace boost::xpressive; local result; std::map map1; map1["a"] = "1"; map1["b"] = "2"; std::map map2; map2["c"] = "3"; map2["d"] = "4"; std::string str("abcde"); sregex rx = *((a1= map1) | (a1= map2) | 'e') [ result += (a1 | "9") ]; if(!regex_match(str, rx)) { BOOST_ERROR("oops"); } else { BOOST_CHECK_EQUAL(result.get(), "12349"); } } #ifndef BOOST_XPRESSIVE_NO_WREGEX struct City { std::wstring name; char const* nickname; int population; }; BOOST_TYPEOF_REGISTER_TYPE(City) /////////////////////////////////////////////////////////////////////////////// // test8 // test wide strings with structure result void test8() { using namespace boost::xpressive; City cities[] = { {L"Chicago", "The Windy City", 945000}, {L"New York", "The Big Apple", 16626000}, {L"\u041c\u043E\u0441\u043A\u0432\u0430", "Moscow", 9299000} }; int const nbr_cities = sizeof(cities)/sizeof(*cities); std::map map1; for(int i=0; i result1, result2; wsregex rx = (a1= map1)[ result1 = a1 ] >> +_s >> (a1= map1)[ result2 = a1 ]; if(!regex_match(str, rx)) { BOOST_ERROR("oops"); } else { BOOST_CHECK_EQUAL(result1.get().nickname, "The Windy City"); BOOST_CHECK_EQUAL(result2.get().nickname, "Moscow"); } } #else void test8() { // This test is empty } #endif /////////////////////////////////////////////////////////////////////////////// // test9 // test "not before" using a map void test9() { using namespace boost::xpressive; std::string result; std::string str("foobar"); std::map map1; map1["foo"] = 1; sregex rx = ~before((a1=map1)[a1]) >> (s1=*_w)[ xp::ref(result) = s1 ]; if(!regex_match(str, rx)) { BOOST_CHECK_EQUAL(result, ""); } else { BOOST_ERROR("oops"); } } 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_symbols"); 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(&test5)); test->add(BOOST_TEST_CASE(&test6)); test->add(BOOST_TEST_CASE(&test7)); test->add(BOOST_TEST_CASE(&test8)); test->add(BOOST_TEST_CASE(&test9)); return test; }