c8c65757c6
[SVN r82191]
270 lines
13 KiB
C++
270 lines
13 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2001-2011 Joel de Guzman
|
|
Copyright (c) 2011 Thomas Bernard
|
|
|
|
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 <vector>
|
|
|
|
#include <boost/detail/lightweight_test.hpp>
|
|
#include <boost/utility/enable_if.hpp>
|
|
|
|
#include <boost/spirit/include/qi_operator.hpp>
|
|
#include <boost/spirit/include/qi_char.hpp>
|
|
#include <boost/spirit/include/qi_string.hpp>
|
|
#include <boost/spirit/include/qi_numeric.hpp>
|
|
#include <boost/spirit/include/qi_directive.hpp>
|
|
#include <boost/spirit/include/qi_action.hpp>
|
|
#include <boost/spirit/include/qi_nonterminal.hpp>
|
|
#include <boost/spirit/include/support_argument.hpp>
|
|
#include <boost/spirit/include/phoenix_core.hpp>
|
|
#include <boost/spirit/include/phoenix_operator.hpp>
|
|
#include <boost/spirit/include/phoenix_container.hpp>
|
|
#include <boost/spirit/repository/include/qi_kwd.hpp>
|
|
#include <boost/spirit/repository/include/qi_keywords.hpp>
|
|
|
|
#include <string>
|
|
#include <iostream>
|
|
#include "test.hpp"
|
|
|
|
struct x_attr
|
|
{
|
|
|
|
};
|
|
|
|
namespace boost { namespace spirit { namespace traits
|
|
{
|
|
|
|
|
|
template <>
|
|
struct container_value<x_attr>
|
|
{
|
|
typedef char type; // value type of container
|
|
};
|
|
|
|
|
|
template <>
|
|
struct push_back_container<x_attr, char>
|
|
{
|
|
static bool call(x_attr& /*c*/, char /*val*/)
|
|
{
|
|
// push back value type into container
|
|
return true;
|
|
}
|
|
};
|
|
}}}
|
|
|
|
int
|
|
main()
|
|
{
|
|
using spirit_test::test_attr;
|
|
using spirit_test::test;
|
|
using namespace boost::spirit;
|
|
using namespace boost::spirit::ascii;
|
|
using boost::spirit::repository::kwd;
|
|
using boost::spirit::repository::ikwd;
|
|
using boost::spirit::repository::dkwd;
|
|
using boost::spirit::qi::inf;
|
|
using boost::spirit::qi::omit;
|
|
using boost::spirit::qi::int_;
|
|
using boost::spirit::qi::lit;
|
|
using boost::spirit::qi::_1;
|
|
using boost::spirit::qi::lexeme;
|
|
|
|
|
|
{
|
|
|
|
// no constraints
|
|
boost::fusion::vector<char,char,int> data;
|
|
BOOST_TEST( test_attr("c=1 a=a", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], data, space));
|
|
BOOST_TEST( boost::fusion::at_c<0>(data) == 'a' );
|
|
BOOST_TEST( boost::fusion::at_c<1>(data) == 0 );
|
|
BOOST_TEST( boost::fusion::at_c<2>(data) == 1 );
|
|
|
|
BOOST_TEST( test("a=a c=1", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
|
|
BOOST_TEST( test("", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
|
|
// Exact
|
|
BOOST_TEST(test("a=a b=b c=1", kwd("a",1)[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
BOOST_TEST(test("a=a b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
BOOST_TEST(!test("b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
|
|
// Min - Max
|
|
BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
|
|
BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
|
|
BOOST_TEST(test("a=g a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
|
|
BOOST_TEST(!test("a=f a=e b=c b=e a=p c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
|
|
|
|
// Min - inf
|
|
BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
|
|
BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
|
|
BOOST_TEST(test("a=f a=f a=g b=c b=e c=1 a=e", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
|
|
}
|
|
|
|
{ // Single keyword, empty string
|
|
BOOST_TEST(test(" ", kwd("aad")[char_],space));
|
|
// Single keyword
|
|
BOOST_TEST(test("aad E ", kwd("aad")[char_],space));
|
|
// Single no case keyword
|
|
BOOST_TEST(test("AaD E ", ikwd("aad")[char_],space));
|
|
|
|
}
|
|
|
|
{
|
|
// Vector container
|
|
boost::fusion::vector<std::vector<int>,std::vector<int>,std::vector<int> > data;
|
|
BOOST_TEST(test_attr(" a=1 b=2 b=5 c=3",kwd("a")[ '=' > int_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] , data, space)
|
|
&& (boost::fusion::at_c<0>(data).size()==1)
|
|
&& (boost::fusion::at_c<0>(data)[0]==1)
|
|
|
|
&&(boost::fusion::at_c<1>(data).size()==2)
|
|
&&(boost::fusion::at_c<1>(data)[0]==2)
|
|
&&(boost::fusion::at_c<1>(data)[1]==5)
|
|
|
|
&&(boost::fusion::at_c<2>(data).size()==1)
|
|
&&(boost::fusion::at_c<2>(data)[0]==3)
|
|
);
|
|
}
|
|
|
|
{
|
|
// no_case test
|
|
BOOST_TEST( test("B=a c=1 a=E", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space));
|
|
BOOST_TEST( test("B=a c=1 a=e", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space));
|
|
BOOST_TEST( !test("B=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
BOOST_TEST( test("b=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
BOOST_TEST( !test("A=a c=1 a=E", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
BOOST_TEST( test("A=a c=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
BOOST_TEST( !test("A=a C=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
}
|
|
|
|
{
|
|
// iterator restoration
|
|
BOOST_TEST( test("a=a c=1 ba=d", (kwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) > lit("ba=") > char_, space));
|
|
BOOST_TEST( test("A=a c=1 ba=d", (ikwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) > lit("ba=") > char_, space));
|
|
}
|
|
|
|
{ // actions
|
|
namespace phx = boost::phoenix;
|
|
|
|
std::vector<int> v;
|
|
BOOST_TEST(test("b=2 c=4", kwd("b")['=' > int_][phx::ref(v)=_1] / kwd("c")[ '=' > int_ ],space) &&
|
|
v[0] == 2 );
|
|
}
|
|
|
|
|
|
{
|
|
// no constraints
|
|
boost::fusion::vector<char,char,int> data;
|
|
BOOST_TEST( test_attr("c,1,2=1 2,b=a", kwd( char_ >> lit(',') >> int_ )[ '=' >> char_] / kwd(int_ >> lit(',') >> char_)[ '=' >> char_] / kwd(char_ >> lit(',') >> int_ >> lit(',') >> int_)['=' >> int_], data, space));
|
|
BOOST_TEST( boost::fusion::at_c<0>(data) == 0 );
|
|
BOOST_TEST( boost::fusion::at_c<1>(data) == 'a');
|
|
BOOST_TEST( boost::fusion::at_c<2>(data) == 1 );
|
|
|
|
BOOST_TEST( test("2,b=a c,1,2=1", kwd( char_ >> ',' >> int_ )[ '=' >> char_] / kwd(int_ >> ',' >> char_)[ '=' >> char_] / kwd(char_ >> ',' >> int_ >> ',' >> int_)['=' >> int_], space));
|
|
|
|
BOOST_TEST( test("", kwd( char_ >> ',' >> int_ )[ '=' >> char_] / kwd(int_ >> ',' >> char_)[ '=' >> char_] / kwd(char_ >> ',' >> int_ >> ',' >> int_)['=' >> int_], space));
|
|
|
|
// Exact
|
|
BOOST_TEST(test("7a=a 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'))[ '=' >> char_] / kwd(int_ >> lit('c'))['=' >> int_], space));
|
|
BOOST_TEST(test("7a=a 3b=d 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'),2)[ '=' >> char_] / kwd(int_ >>'c')['=' >> int_], space));
|
|
BOOST_TEST(!test("7a=a 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'),2)[ '=' >> char_] / kwd(int_ >>'c')['=' >> int_], space));
|
|
|
|
// Min - Max
|
|
BOOST_TEST(test("6a=f 2b=c 3b=e 1c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,2)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
|
|
BOOST_TEST(!test("1b=c 6b=e 2c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,1)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
|
|
BOOST_TEST(test("4a=g 7a=f 2b=c 1b=e 4c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,2)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
|
|
BOOST_TEST(!test("1a=f a=e 2b=c 5b=e 6a=p 67c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,1)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
|
|
|
|
// Min - inf
|
|
BOOST_TEST(test("41a=f 44b=c 12b=e 45c=1", kwd(int_ >> "a",1,inf)[ '=' >> char_] / kwd(int_ >> "b",0,inf)[ '=' >> char_] / kwd(int_ >> "c",1,inf)['=' >> int_], space ));
|
|
BOOST_TEST(!test("31b=c 55b=e 2c=1", kwd("a",1,inf)[ '=' >> char_] / kwd("b",0,inf)[ '=' >> char_] / kwd("c",1,inf)['=' >> int_], space ));
|
|
BOOST_TEST(test("12a=f 45a=f 12a=g 1b=c 7b=e 12c=1 6a=e", kwd(int_ >> "a",1,inf)[ '=' >> char_] / kwd(int_ >> "b",0,inf)[ '=' >> char_] / kwd(int_ >> "c",1,inf)['=' >> int_], space ));
|
|
|
|
}
|
|
|
|
{
|
|
|
|
// Vector container
|
|
boost::fusion::vector<std::vector<int>,std::vector<int>,std::vector<int> > data;
|
|
BOOST_TEST(test_attr(" 41a=1 4b=2 12b=5 5c=3",kwd(int_ >> "a")[ '=' >> int_] / kwd(int_ >> "b")[ '=' >> int_] / kwd(int_ >> "c")['=' >> int_] , data, space)
|
|
&& (boost::fusion::at_c<0>(data).size()==1)
|
|
&& (boost::fusion::at_c<0>(data)[0]==1)
|
|
|
|
&&(boost::fusion::at_c<1>(data).size()==2)
|
|
&&(boost::fusion::at_c<1>(data)[0]==2)
|
|
&&(boost::fusion::at_c<1>(data)[1]==5)
|
|
|
|
&&(boost::fusion::at_c<2>(data).size()==1)
|
|
&&(boost::fusion::at_c<2>(data)[0]==3)
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
{
|
|
// no_case test
|
|
BOOST_TEST( test("12B=a 5c=1 1a=E", no_case[kwd(int_ >> "a")[ "=E" ] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_]], space));
|
|
BOOST_TEST( test("5B=a 2c=1 5a=e", no_case[kwd(int_ >> "a")[ "=E" ] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_]], space));
|
|
BOOST_TEST( !test("1B=a 8c=1 1A=E", no_case[kwd(int_ >> "a")[ '=' >> char_]] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
|
|
BOOST_TEST( test("2b=a 6c=1 5A=E", no_case[kwd(int_ >> "a")[ '=' >> char_]] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
|
|
BOOST_TEST( !test("1A=a 5c=1 1a=E", kwd(int_ >> "a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
|
|
BOOST_TEST( test("A=a 23c=1 a=E", ikwd("a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
|
|
BOOST_TEST( !test("A=a 21C=1 a=E", ikwd("a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
|
|
}
|
|
|
|
{
|
|
// iterator restoration
|
|
BOOST_TEST( test("4a=a c4=1 ba=d", (kwd(int_ >> "a")[ '=' >> char_] / kwd("b" >> int_)[ '=' >> int_] / kwd("c" >> int_ )['=' >> int_] ) >> lit("ba=") >> char_, space));
|
|
}
|
|
|
|
{ // actions
|
|
namespace phx = boost::phoenix;
|
|
|
|
std::vector<int> v;
|
|
BOOST_TEST(test("b4=2 c1=4", kwd("b" >> int_)['=' >> int_][phx::ref(v)=_1] / kwd("c" >> int_)[ '=' >> int_ ],space) &&
|
|
v[0] == 2 );
|
|
}
|
|
|
|
{
|
|
// complex keyword single test
|
|
int result=0;
|
|
|
|
BOOST_TEST( test_attr("(a,1) = 3214", kwd( '(' >> char_ >> ',' >> int_ >> ')' )['=' >> int_], result, space) );
|
|
BOOST_TEST(result==3214);
|
|
}
|
|
{
|
|
// Mixed complex keyword loop
|
|
boost::fusion::vector<int,int,int> data;
|
|
|
|
BOOST_TEST( test_attr("(a,1) = 3214 b += 2 hello 10 (a,2)=31", kwd( '(' >> char_ >> ',' >> int_ >> ')' )['=' >> int_] / kwd("hello")[int_] / kwd("b")["+=" >> int_], data, space) );
|
|
BOOST_TEST( boost::fusion::at_c<0>(data) == 31);
|
|
BOOST_TEST( boost::fusion::at_c<1>(data) == 10);
|
|
BOOST_TEST( boost::fusion::at_c<2>(data) == 2);
|
|
}
|
|
|
|
// dkwd and idkwd
|
|
{
|
|
BOOST_TEST( test("a =a", dkwd("a")[ '=' > char_] , space));
|
|
BOOST_TEST( !test("a=a", dkwd("a")[ '=' > char_] , space));
|
|
BOOST_TEST(test("a =a b =b c=1", dkwd("a",1)[ '=' > char_] / dkwd("b",1,2)[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
BOOST_TEST(!test("a=a b=b c =1", dkwd("a",1)[ '=' > char_] / dkwd("b",1,2)[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
|
|
BOOST_TEST(test("a =a b =b b =d c=1", dkwd("a",1,inf)[ '=' > char_] / dkwd("b",2,inf)[ '=' > char_] / kwd("c")['=' > int_], space));
|
|
|
|
}
|
|
|
|
{ // attribute customization
|
|
|
|
// x_attr x;
|
|
// test_attr("a = b c = d", kwd("a")['=' > char_] / kwd("c")['=' > char_], x);
|
|
}
|
|
|
|
|
|
return boost::report_errors();
|
|
}
|
|
|