123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- ///////////////////////////////////////////////////////////////////////////////
- // 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 <string>
- #include <map>
- #include <boost/version.hpp>
- #include <boost/xpressive/xpressive_static.hpp>
- #include <boost/xpressive/regex_actions.hpp>
- #include <boost/test/unit_test.hpp>
- #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<std::string> result;
- std::string str("foo bar baz foo bar baz");
- std::map<std::string,std::string> 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<std::string> result;
- std::string str("foobarbazfoobazbazfoobazbar");
- std::map<std::string,std::string> 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<int> result;
- std::string str("foo bar baz bop");
- std::map<std::string,int> 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<std::string, int> > const _map = {};
- std::string str("aaa=>1 bbb=>2 ccc=>3");
- std::map<std::string,std::string> map1;
- map1["aaa"] = "foo";
- map1["bbb"] = "bar";
- map1["ccc"] = "baz";
- std::map<std::string,int> 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<std::string, int> 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<int> result(0);
- std::string str("abcdefghi");
- std::map<std::string,int> map1;
- std::map<std::string,int> map2;
- std::map<std::string,int> map3;
- std::map<std::string,int> map4;
- std::map<std::string,int> map5;
- std::map<std::string,int> map6;
- std::map<std::string,int> map7;
- std::map<std::string,int> map8;
- std::map<std::string,int> 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<std::string> result;
- std::map<std::string,std::string> 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<std::string> result;
- std::map<std::string,std::string> map1;
- map1["a"] = "1";
- map1["b"] = "2";
- std::map<std::string,std::string> 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<std::wstring, City> map1;
- for(int i=0; i<nbr_cities; ++i)
- {
- map1[cities[i].name] = cities[i];
- }
- std::wstring str(L"Chicago \u041c\u043E\u0441\u043A\u0432\u0430");
- local<City> 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<std::string,int> 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;
- }
|