Example #1
0
int main()
{
    using spirit_test::test;
    using spirit_test::test_delimited;
    using boost::spirit::utree;
    using boost::spirit::utree_type;
    using boost::spirit::utf8_string_range_type;
    using boost::spirit::utf8_string_type;
    using boost::spirit::utf8_symbol_type;

    using boost::spirit::karma::char_;
    using boost::spirit::karma::bool_;
    using boost::spirit::karma::int_;
    using boost::spirit::karma::double_;
    using boost::spirit::karma::string;
    using boost::spirit::karma::space;
    using boost::spirit::karma::rule;

    typedef spirit_test::output_iterator<char>::type output_iterator;

    // as_string
    {   
        using boost::spirit::karma::digit;
        using boost::spirit::karma::as_string;

        utree ut("xy");
        BOOST_TEST(test("xy", string, ut));
        BOOST_TEST(test("xy", as_string[*char_], ut));
        BOOST_TEST(test("x,y", as_string[char_ << ',' << char_], ut));

        ut.clear();
        ut.push_back("ab");
        ut.push_back(1.2);
        BOOST_TEST(test("ab1.2", as_string[*~digit] << double_, ut));
        BOOST_TEST(test("a,b1.2", as_string[~digit % ','] << double_, ut));
    }
    
    // as
    {
        using boost::spirit::karma::digit;
        using boost::spirit::karma::as;
        
        typedef as<std::string> as_string_type;
        as_string_type const as_string = as_string_type();

        typedef as<utf8_symbol_type> as_symbol_type;
        as_symbol_type const as_symbol = as_symbol_type();

        utree ut("xy");
        BOOST_TEST(test("xy", string, ut));
        BOOST_TEST(test("xy", as_string[*char_], ut));
        BOOST_TEST(test("x,y", as_string[char_ << ',' << char_], ut));

        ut.clear();
        ut.push_back("ab");
        ut.push_back(1.2);
        BOOST_TEST(test("ab1.2", as_string[*~digit] << double_, ut));
        BOOST_TEST(test("a,b1.2", as_string[~digit % ','] << double_, ut));
        
        ut = utf8_symbol_type("xy");
        BOOST_TEST(test("xy", string, ut));
        BOOST_TEST(test("xy", as_symbol[*char_], ut));
        BOOST_TEST(test("x,y", as_symbol[char_ << ',' << char_], ut));

        ut.clear();
        ut.push_back(utf8_symbol_type("ab"));
        ut.push_back(1.2);
        BOOST_TEST(test("ab1.2", as_symbol[*~digit] << double_, ut));
        BOOST_TEST(test("a,b1.2", as_symbol[~digit % ','] << double_, ut));
    }
    
    // typed basic_string rules
    {
        utree ut("buzz");

        rule<output_iterator, utf8_string_type()> r1 = string;
        rule<output_iterator, utf8_symbol_type()> r2 = string;

        BOOST_TEST(test("buzz", r1, ut));

        ut = utf8_symbol_type("bar");
        BOOST_TEST(test("bar", r2, ut));
    }

    // parameterized karma::string
    {
        utree ut("foo");

        rule<output_iterator, utf8_string_type()> r1 = string("foo");
        BOOST_TEST(test("foo", string("foo"), ut));
        BOOST_TEST(test("foo", r1, ut));
    }

    {
        using boost::spirit::karma::verbatim;
        using boost::spirit::karma::repeat;
        using boost::spirit::karma::space;
        using boost::spirit::karma::digit;

        utree ut;
        ut.push_back('x');
        ut.push_back('y');
        ut.push_back('c');
        BOOST_TEST(test_delimited("xy c ", verbatim[repeat(2)[char_]] << char_, ut, space));
        BOOST_TEST(test_delimited("x yc ", char_ << verbatim[*char_], ut, space));

        ut.clear();
        ut.push_back('a');
        ut.push_back('b');
        ut.push_back(1.2);
        BOOST_TEST(test_delimited("ab 1.2 ", verbatim[repeat(2)[~digit]] << double_, ut, space));
    }

    return boost::report_errors();
}
Example #2
0
int
main()
{
    using spirit_test::test_attr;
    using spirit_test::test;

    using namespace boost::spirit::ascii;
    using namespace boost::spirit::qi::labels;
    using boost::spirit::qi::locals;
    using boost::spirit::qi::rule;
    using boost::spirit::qi::int_;
    using boost::spirit::qi::uint_;
    using boost::spirit::qi::fail;
    using boost::spirit::qi::on_error;
    using boost::spirit::qi::debug;
    using boost::spirit::qi::lit;

    namespace phx = boost::phoenix;

    { // basic tests

        rule<char const*> a, b, c, start;

        a = 'a';
        b = 'b';
        c = 'c';

        a.name("a");
        b.name("b");
        c.name("c");
        start.name("start");

        debug(a);
        debug(b);
        debug(c);
        debug(start);

        start = *(a | b | c);
        BOOST_TEST(test("abcabcacb", start));

        start = (a | b) >> (start | b);
        BOOST_TEST(test("aaaabababaaabbb", start));
        BOOST_TEST(test("aaaabababaaabba", start, false));

        // ignore the skipper!
        BOOST_TEST(test("aaaabababaaabba", start, space, false));
    }

    { // basic tests with direct initialization

        rule<char const*> a ('a');
        rule<char const*> b ('b');
        rule<char const*> c ('c');
        rule<char const*> start = (a | b) >> (start | b);

        BOOST_TEST(test("aaaabababaaabbb", start));
        BOOST_TEST(test("aaaabababaaabba", start, false));

        // ignore the skipper!
        BOOST_TEST(test("aaaabababaaabba", start, space, false));
    }

    { // basic tests w/ skipper
        rule<char const*, space_type> a, b, c, start;

        a = 'a';
        b = 'b';
        c = 'c';

        a.name("a");
        b.name("b");
        c.name("c");
        start.name("start");

        debug(a);
        debug(b);
        debug(c);
        debug(start);

        start = *(a | b | c);
        BOOST_TEST(test(" a b c a b c a c b ", start, space));

        start = (a | b) >> (start | b);
        BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start, space));
        BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start, space, false));
    }

    { // basic tests w/ skipper but no final post-skip

        rule<char const*, space_type> a, b, c, start;

        a = 'a';
        b = 'b';
        c = 'c';

        a.name("a");
        b.name("b");
        c.name("c");
        start.name("start");

        debug(a);
        debug(b);
        debug(c);
        debug(start);

        start = *(a | b) >> c;

        using boost::spirit::qi::phrase_parse;
        using boost::spirit::qi::skip_flag;
        {
            char const *s1 = " a b a a b b a c ... "
              , *const e1 = s1 + std::strlen(s1);
            BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::dont_postskip)
              && s1 == e1 - 5);
        }

        start = (a | b) >> (start | c);
        {
            char const *s1 = " a a a a b a b a b a a a b b b c "
              , *const e1 = s1 + std::strlen(s1);
            BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::postskip)
              && s1 == e1);
        }
        {
            char const *s1 = " a a a a b a b a b a a a b b b c "
              , *const e1 = s1 + std::strlen(s1);
            BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::dont_postskip)
              && s1 == e1 - 1);
        }
    }

    return boost::report_errors();
}
Example #3
0
int
main()
{
    using spirit_test::test;
    using spirit_test::test_attr;
    using boost::spirit::x3::symbols;
    using boost::spirit::x3::rule;
    //~ using boost::spirit::x3::lazy;
    //~ using boost::spirit::x3::_r1;

    { // construction from symbol array
        char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"};
        symbols<char, int> sym(syms);

        BOOST_TEST((test("Joel", sym)));
        BOOST_TEST((test("Ruby", sym)));
        BOOST_TEST((test("Tenji", sym)));
        BOOST_TEST((test("Tutit", sym)));
        BOOST_TEST((test("Kim", sym)));
        BOOST_TEST((test("Joey", sym)));
        BOOST_TEST((!test("XXX", sym)));
    }

    { // construction from 2 arrays

        char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"};
        int data[] = {1,2,3,4,5,6};
        symbols<char, int> sym(syms, data);

        int i;
        BOOST_TEST((test_attr("Joel", sym, i)));
        BOOST_TEST(i == 1);
        BOOST_TEST((test_attr("Ruby", sym, i)));
        BOOST_TEST(i == 2);
        BOOST_TEST((test_attr("Tenji", sym, i)));
        BOOST_TEST(i == 3);
        BOOST_TEST((test_attr("Tutit", sym, i)));
        BOOST_TEST(i == 4);
        BOOST_TEST((test_attr("Kim", sym, i)));
        BOOST_TEST(i == 5);
        BOOST_TEST((test_attr("Joey", sym, i)));
        BOOST_TEST(i == 6);
        BOOST_TEST((!test_attr("XXX", sym, i)));
    }

    { // allow std::string and other string types
        symbols<> sym;

        // const and non-const std::string
        std::string a("abc");
        std::string const b("def");
        sym += a;
        sym += b;
        BOOST_TEST((test("abc", sym)));
        BOOST_TEST((test("def", sym)));
        sym = a;
        BOOST_TEST((test("abc", sym)));
        BOOST_TEST((!test("def", sym)));

        // non-const C-style string
        char arr[2]; arr[0] = 'a'; arr[1] = '\0';
        sym = arr;
        BOOST_TEST((test("a", sym)));
        BOOST_TEST((!test("b", sym)));

        // const and non-const custom string type
        custom_string_c c('x');
        custom_string_c const cc('y');
        sym = c, cc;
        BOOST_TEST((test("x", sym)));
        BOOST_TEST((test("y", sym)));
        BOOST_TEST((!test("z", sym)));
    }

    // $$$ Not yet implemented $$$
    //~ {
        //~ namespace phx = boost::phoenix;

        //~ symbols<char, int> sym;
        //~ sym.add
            //~ ("a", 1)
            //~ ("b", 2)
        //~ ;

        //~ rule<char const*, int(symbols<char, int>&)> r;
        //~ r %= lazy(_r1);

        //~ int i = 0;
        //~ BOOST_TEST(test_attr("a", r(phx::ref(sym)), i));
        //~ BOOST_TEST(i == 1);
        //~ BOOST_TEST(test_attr("b", r(phx::ref(sym)), i));
        //~ BOOST_TEST(i == 2);
        //~ BOOST_TEST(!test("c", r(phx::ref(sym))));
    //~ }

    { // find

        symbols<char, int> sym;
        sym.add("a", 1)("b", 2);

        BOOST_TEST(!sym.find("c"));

        BOOST_TEST(sym.find("a") && *sym.find("a") == 1);
        BOOST_TEST(sym.find("b") && *sym.find("b") == 2);

        BOOST_TEST(sym.at("a") == 1);
        BOOST_TEST(sym.at("b") == 2);
        BOOST_TEST(sym.at("c") == 0);

        BOOST_TEST(sym.find("a") && *sym.find("a") == 1);
        BOOST_TEST(sym.find("b") && *sym.find("b") == 2);
        BOOST_TEST(sym.find("c") && *sym.find("c") == 0);

        symbols<char, int> const_sym(sym);

        BOOST_TEST(const_sym.find("a") && *const_sym.find("a") == 1);
        BOOST_TEST(const_sym.find("b") && *const_sym.find("b") == 2);
        BOOST_TEST(const_sym.find("c") && *const_sym.find("c") == 0);
        BOOST_TEST(!const_sym.find("d"));

        char const *str1 = "all";
        char const *first = str1, *last = str1 + 3;
        BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str1 + 1);

        char const *str2 = "dart";
        first = str2; last = str2 + 4;
        BOOST_TEST(!sym.prefix_find(first, last) && first == str2);
    }

    { // name
        symbols <char, int> sym,sym2;
        sym.name("test");
        BOOST_TEST(sym.name()=="test");
        sym2 = sym;
        BOOST_TEST(sym2.name()=="test");

        symbols <char,int> sym3(sym);
        BOOST_TEST(sym3.name()=="test");
    }

    { // Substrings

        symbols<char, int> sym;
        BOOST_TEST(sym.at("foo") == 0);
        sym.at("foo") = 1;
        BOOST_TEST(sym.at("foo") == 1);
        BOOST_TEST(sym.at("fool") == 0);
        sym.at("fool") = 2;
        BOOST_TEST(sym.find("foo") && *sym.find("foo") == 1);
        BOOST_TEST(sym.find("fool") && *sym.find("fool") == 2);
        BOOST_TEST(!sym.find("foolish"));
        BOOST_TEST(!sym.find("foot"));
        BOOST_TEST(!sym.find("afoot"));

        char const *str, *first, *last;
        str = "foolish"; first = str; last = str + 7;
        BOOST_TEST(*sym.prefix_find(first, last) == 2 && first == str + 4);

        first = str; last = str + 4;
        BOOST_TEST(*sym.prefix_find(first, last) == 2 && first == str + 4);

        str = "food"; first = str; last = str + 4;
        BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str + 3);

        first = str; last = str + 3;
        BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str + 3);

        first = str; last = str + 2;
        BOOST_TEST(!sym.prefix_find(first, last) && first == str);
    }

    {
        // remove bug

        std::string s;
        symbols<char, double> vars;

        vars.add("l1", 12.0);
        vars.add("l2", 0.0);
        vars.remove("l2");
        vars.find("l1");
        double* d = vars.find("l1");
        BOOST_TEST(d != 0);
    }

    { // test for proto problem with rvalue references (10-11-2011)
        symbols<char, int> sym;
        sym += get_str("Joel");
        sym += get_str("Ruby");

        BOOST_TEST((test("Joel", sym)));
        BOOST_TEST((test("Ruby", sym)));
    }

    return boost::report_errors();
}
Example #4
0
int
main()
{
    using spirit_test::test_attr;
    using spirit_test::test;

    using namespace boost::spirit::ascii;
    using boost::spirit::qi::repeat;
    using boost::spirit::qi::inf;
    using boost::spirit::qi::omit;
    using boost::spirit::qi::int_;
    using boost::spirit::qi::_1;
    using boost::spirit::qi::lexeme;

    {
        BOOST_TEST(test("aaaaaaaa", repeat[char_])); // kleene synonym
        BOOST_TEST(test("aaaaaaaa", repeat(8)[char_]));
        BOOST_TEST(!test("aa", repeat(3)[char_]));

        BOOST_TEST(test("aaa", repeat(3, 5)[char_]));
        BOOST_TEST(test("aaaaa", repeat(3, 5)[char_]));
        BOOST_TEST(!test("aaaaaa", repeat(3, 5)[char_]));
        BOOST_TEST(!test("aa", repeat(3, 5)[char_]));

        BOOST_TEST(test("aaa", repeat(3, inf)[char_]));
        BOOST_TEST(test("aaaaa", repeat(3, inf)[char_]));
        BOOST_TEST(test("aaaaaa", repeat(3, inf)[char_]));
        BOOST_TEST(!test("aa", repeat(3, inf)[char_]));
    }

    {
        std::string s;
        BOOST_TEST(test_attr("aaaaaaaa", repeat[char_ >> char_], s)); // kleene synonym
        BOOST_TEST(s == "aaaaaaaa");

        s.clear();
        BOOST_TEST(test_attr("aaaaaaaa", repeat(4)[char_ >> char_], s));
        BOOST_TEST(s == "aaaaaaaa");

        BOOST_TEST(!test("aa", repeat(3)[char_ >> char_]));
        BOOST_TEST(!test("a", repeat(1)[char_ >> char_]));

        s.clear();
        BOOST_TEST(test_attr("aa", repeat(1, 3)[char_ >> char_], s));
        BOOST_TEST(s == "aa");

        s.clear();
        BOOST_TEST(test_attr("aaaaaa", repeat(1, 3)[char_ >> char_], s));
        BOOST_TEST(s == "aaaaaa");

        BOOST_TEST(!test("aaaaaaa", repeat(1, 3)[char_ >> char_]));
        BOOST_TEST(!test("a", repeat(1, 3)[char_ >> char_]));

        s.clear();
        BOOST_TEST(test_attr("aaaa", repeat(2, inf)[char_ >> char_], s));
        BOOST_TEST(s == "aaaa");

        s.clear();
        BOOST_TEST(test_attr("aaaaaa", repeat(2, inf)[char_ >> char_], s));
        BOOST_TEST(s == "aaaaaa");

        BOOST_TEST(!test("aa", repeat(2, inf)[char_ >> char_]));
    }

    { // from classic spirit tests
        BOOST_TEST(test("", repeat(0, inf)['x']));

        //  repeat exact 8
        #define rep8 repeat(8)[alpha] >> 'X'
        BOOST_TEST(!test("abcdefgX", rep8, false));
        BOOST_TEST(test("abcdefghX", rep8));
        BOOST_TEST(!test("abcdefghiX", rep8, false));
        BOOST_TEST(!test("abcdefgX", rep8, false));
        BOOST_TEST(!test("aX", rep8, false));

        //  repeat 2 to 8
        #define rep28 repeat(2, 8)[alpha] >> '*'
        BOOST_TEST(test("abcdefg*", rep28));
        BOOST_TEST(test("abcdefgh*", rep28));
        BOOST_TEST(!test("abcdefghi*", rep28, false));
        BOOST_TEST(!test("a*", rep28, false));

        //  repeat 2 or more
        #define rep2_ repeat(2, inf)[alpha] >> '+'
        BOOST_TEST(test("abcdefg+", rep2_));
        BOOST_TEST(test("abcdefgh+", rep2_));
        BOOST_TEST(test("abcdefghi+", rep2_));
        BOOST_TEST(test("abcdefg+", rep2_));
        BOOST_TEST(!test("a+", rep2_, false));

        //  repeat 0
        #define rep0 repeat(0)[alpha] >> '/'
        BOOST_TEST(test("/", rep0));
        BOOST_TEST(!test("a/", rep0, false));

        //  repeat 0 or 1
        #define rep01 repeat(0, 1)[alpha >> digit] >> '?'
        BOOST_TEST(!test("abcdefg?", rep01, false));
        BOOST_TEST(!test("a?", rep01, false));
        BOOST_TEST(!test("1?", rep01, false));
        BOOST_TEST(!test("11?", rep01, false));
        BOOST_TEST(!test("aa?", rep01, false));
        BOOST_TEST(test("?", rep01));
        BOOST_TEST(test("a1?", rep01));
    }

    {
        BOOST_TEST(test(" a a aaa aa", repeat(7)[char_], space));
        BOOST_TEST(test("12345 678 9", repeat(9)[digit], space));
    }

    {
        BOOST_TEST(test("aBcdeFGH", no_case[repeat(8)[lower]]));
        BOOST_TEST(test("a B cde FGH", no_case[repeat(8)[lower]], space));
    }

    {
        std::vector<std::string> v;
        BOOST_TEST(test_attr("a b c d", repeat(4)[lexeme[+alpha]], v, space) && 4 == v.size() &&
            v[0] == "a" && v[1] == "b" && v[2] == "c" &&  v[3] == "d");
    }
    
    {
        std::string s;
        BOOST_TEST(test_attr("bbbb", repeat(4)[char_], s) && s == "bbbb");

        s.clear();
        BOOST_TEST(test_attr("b b b b", repeat(4)[char_], s, space) && s == "bbbb");

        // The following 2 tests show that omit does not inhibit explicit attributes
        s.clear();
        BOOST_TEST(test_attr("bbbb", omit[repeat(4)[char_('b')]], s) && s == "bbbb");

        s.clear();
        BOOST_TEST(test_attr("b b b b", omit[repeat(4)[char_('b')]], s, space) && s == "bbbb");
    }

    {
        BOOST_TEST(test("1 2 3", int_ >> repeat(2)[int_], space));
        BOOST_TEST(!test("1 2", int_ >> repeat(2)[int_], space));
    }

    {
        std::vector<char> v;
        BOOST_TEST(test_attr("1 2 3", int_ >> repeat(2)[int_], v, space));
        BOOST_TEST(v.size() == 3 && v[0] == 1 && v[1] == 2 && v[2] == 3);

        BOOST_TEST(!test("1 2", int_ >> repeat(2)[int_], space));
    }

    { // actions
        namespace phx = boost::phoenix;

        std::vector<char> v;
        BOOST_TEST(test("bbbb", repeat(4)[char_][phx::ref(v) = _1]) && 4 == v.size() &&
            v[0] == 'b' && v[1] == 'b' && v[2] == 'b' &&  v[3] == 'b');
    }

    { // more actions
        namespace phx = boost::phoenix;

        std::vector<int> v;
        BOOST_TEST(test("123 456 789", repeat(3)[int_][phx::ref(v) = _1], space) && 3 == v.size() &&
            v[0] == 123 && v[1] == 456 && v[2] == 789);
    }

    { // lazy repeats
        using boost::phoenix::val;

        BOOST_TEST(test("aaaaaaaa", repeat(val(8))[char_]));
        BOOST_TEST(!test("aa", repeat(val(3))[char_]));

        BOOST_TEST(test("aaa", repeat(val(3), val(5))[char_]));
        BOOST_TEST(test("aaaaa", repeat(val(3), val(5))[char_]));
        BOOST_TEST(!test("aaaaaa", repeat(val(3), val(5))[char_]));
        BOOST_TEST(!test("aa", repeat(val(3), val(5))[char_]));

        BOOST_TEST(test("aaa", repeat(val(3), val(inf))[char_]));
        BOOST_TEST(test("aaaaa", repeat(val(3), val(inf))[char_]));
        BOOST_TEST(test("aaaaaa", repeat(val(3), val(inf))[char_]));
        BOOST_TEST(!test("aa", repeat(val(3), val(inf))[char_]));
    }

    { // more lazy repeats
        using boost::phoenix::val;

        BOOST_TEST(test("aaa", repeat(3, val(5))[char_]));
        BOOST_TEST(test("aaaaa", repeat(val(3), 5)[char_]));
        BOOST_TEST(!test("aaaaaa", repeat(3, val(5))[char_]));
        BOOST_TEST(!test("aa", repeat(val(3), 5)[char_]));

//#warning "testcase commented out"
        BOOST_TEST(test("aaa", repeat(val(3), inf)[char_]));
        BOOST_TEST(test("aaaaa", repeat(3, val(inf))[char_]));
        BOOST_TEST(test("aaaaaa", repeat(val(3), inf)[char_]));
        BOOST_TEST(!test("aa", repeat(3, val(inf))[char_]));
    }
    
    { // attribute customization
        
        x_attr x;
        test_attr("abcde", repeat[char_], x);
        test_attr("abcde", repeat(5)[char_], x);
        test_attr("abcde", repeat(1, 5)[char_], x);
        test_attr("abcde", repeat(1, inf)[char_], x);
    }

    return boost::report_errors();
}
Example #5
0
int
main()
{
    using spirit_test::test;
    using spirit_test::test_attr;
    using namespace boost::spirit::ascii;
    using boost::spirit::qi::int_;
    using boost::spirit::qi::omit;
    using boost::spirit::qi::lit;
    using boost::spirit::qi::_1;
    using boost::spirit::qi::lexeme;

    {
        BOOST_TEST(test("aaaaaaaa", +char_));
        BOOST_TEST(test("a", +char_));
        BOOST_TEST(!test("", +char_));
        BOOST_TEST(test("aaaaaaaa", +alpha));
        BOOST_TEST(!test("aaaaaaaa", +upper));
    }

    {
        BOOST_TEST(test(" a a aaa aa", +char_, space));
        BOOST_TEST(test("12345 678 9 ", +digit, space));
    }

    {
        BOOST_TEST(test("aBcdeFGH", no_case[+char_]));
        BOOST_TEST(test("a B cde FGH  ", no_case[+char_], space));
    }

    {
        std::vector<int> v;
        BOOST_TEST(test_attr("123 456 789 10", +int_, v, space) && 4 == v.size() &&
            v[0] == 123 && v[1] == 456 && v[2] == 789 &&  v[3] == 10);
    }

    {
        std::vector<std::string> v;
        BOOST_TEST(test_attr("a b c d", +lexeme[+alpha], v, space) && 4 == v.size() &&
            v[0] == "a" && v[1] == "b" && v[2] == "c" &&  v[3] == "d");
    }
    
    {
        BOOST_TEST(test("Kim Kim Kim", +lit("Kim"), space));
    }

    {
        // The following 2 tests show that omit does not inhibit explicit attributes

        std::string s;
        BOOST_TEST(test_attr("bbbb", omit[+char_('b')], s) && s == "bbbb");

        s.clear();
        BOOST_TEST(test_attr("b b b b ", omit[+char_('b')], s, space) && s == "bbbb");
    }

    { // actions
        namespace phx = boost::phoenix;

        std::vector<char> v;
        BOOST_TEST(test("bbbb", (+char_)[phx::ref(v) = _1]) && 4 == v.size() &&
            v[0] == 'b' && v[1] == 'b' && v[2] == 'b' &&  v[3] == 'b');
    }

    { // more actions
        namespace phx = boost::phoenix;

        std::vector<int> v;
        BOOST_TEST(test("1 2 3", (+int_)[phx::ref(v) = _1], space) && 3 == v.size() &&
            v[0] == 1 && v[1] == 2 && v[2] == 3);
    }
    
    { // attribute customization
        
        x_attr x;
        test_attr("abcde", +char_, x);
    }

    return boost::report_errors();
}
Example #6
0
int
main()
{
    using spirit_test::test;
    using spirit_test::test_attr;
    using namespace boost::spirit::qi;

    { // basics
        symbols<char, int> sym;

        sym.add
            ("Joel")
            ("Ruby")
            ("Tenji")
            ("Tutit")
            ("Kim")
            ("Joey")
        ;

        BOOST_TEST((test("Joel", sym)));
        BOOST_TEST((test("Ruby", sym)));
        BOOST_TEST((test("Tenji", sym)));
        BOOST_TEST((test("Tutit", sym)));
        BOOST_TEST((test("Kim", sym)));
        BOOST_TEST((test("Joey", sym)));
        BOOST_TEST((!test("XXX", sym)));

        sym.remove
            ("Joel")
            ("Ruby")
        ;

        BOOST_TEST((!test("Joel", sym)));
        BOOST_TEST((!test("Ruby", sym)));
    }

    { // comma syntax
        symbols<char, int> sym;
        sym += "Joel", "Ruby", "Tenji", "Tutit", "Kim", "Joey";

        BOOST_TEST((test("Joel", sym)));
        BOOST_TEST((test("Ruby", sym)));
        BOOST_TEST((test("Tenji", sym)));
        BOOST_TEST((test("Tutit", sym)));
        BOOST_TEST((test("Kim", sym)));
        BOOST_TEST((test("Joey", sym)));
        BOOST_TEST((!test("XXX", sym)));

        sym -= "Joel", "Ruby";

        BOOST_TEST((!test("Joel", sym)));
        BOOST_TEST((!test("Ruby", sym)));
    }

    { // no-case handling
        using namespace boost::spirit::ascii;

        symbols<char, int> sym;
        // NOTE: make sure all entries are in lower-case!!!
        sym = "joel", "ruby", "tenji", "tutit", "kim", "joey";

        BOOST_TEST((test("joel", no_case[sym])));
        BOOST_TEST((test("ruby", no_case[sym])));
        BOOST_TEST((test("tenji", no_case[sym])));
        BOOST_TEST((test("tutit", no_case[sym])));
        BOOST_TEST((test("kim", no_case[sym])));
        BOOST_TEST((test("joey", no_case[sym])));

        BOOST_TEST((test("JOEL", no_case[sym])));
        BOOST_TEST((test("RUBY", no_case[sym])));
        BOOST_TEST((test("TENJI", no_case[sym])));
        BOOST_TEST((test("TUTIT", no_case[sym])));
        BOOST_TEST((test("KIM", no_case[sym])));
        BOOST_TEST((test("JOEY", no_case[sym])));
    }

    { // attributes
        symbols<char, int> sym;

        sym.add
            ("Joel", 1)
            ("Ruby", 2)
            ("Tenji", 3)
            ("Tutit", 4)
            ("Kim", 5)
            ("Joey", 6)
        ;

        int i;
        BOOST_TEST((test_attr("Joel", sym, i)));
        BOOST_TEST(i == 1);
        BOOST_TEST((test_attr("Ruby", sym, i)));
        BOOST_TEST(i == 2);
        BOOST_TEST((test_attr("Tenji", sym, i)));
        BOOST_TEST(i == 3);
        BOOST_TEST((test_attr("Tutit", sym, i)));
        BOOST_TEST(i == 4);
        BOOST_TEST((test_attr("Kim", sym, i)));
        BOOST_TEST(i == 5);
        BOOST_TEST((test_attr("Joey", sym, i)));
        BOOST_TEST(i == 6);
        BOOST_TEST((!test_attr("XXX", sym, i)));
    }

    { // actions
        using namespace boost::phoenix;
        using boost::spirit::arg_names::_1;

        symbols<char, int> sym;
        sym.add
            ("Joel", 1)
            ("Ruby", 2)
            ("Tenji", 3)
            ("Tutit", 4)
            ("Kim", 5)
            ("Joey", 6)
        ;

        int i;
        BOOST_TEST((test("Joel", sym[ref(i) = _1])));
        BOOST_TEST(i == 1);
        BOOST_TEST((test("Ruby", sym[ref(i) = _1])));
        BOOST_TEST(i == 2);
        BOOST_TEST((test("Tenji", sym[ref(i) = _1])));
        BOOST_TEST(i == 3);
        BOOST_TEST((test("Tutit", sym[ref(i) = _1])));
        BOOST_TEST(i == 4);
        BOOST_TEST((test("Kim", sym[ref(i) = _1])));
        BOOST_TEST(i == 5);
        BOOST_TEST((test("Joey", sym[ref(i) = _1])));
        BOOST_TEST(i == 6);
        BOOST_TEST((!test("XXX", sym[ref(i) = _1])));
    }

    { // construction from symbol array
        char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"};
        symbols<char, int> sym(syms);

        BOOST_TEST((test("Joel", sym)));
        BOOST_TEST((test("Ruby", sym)));
        BOOST_TEST((test("Tenji", sym)));
        BOOST_TEST((test("Tutit", sym)));
        BOOST_TEST((test("Kim", sym)));
        BOOST_TEST((test("Joey", sym)));
        BOOST_TEST((!test("XXX", sym)));
    }

    { // construction from 2 arrays

        char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"};
        int data[] = {1,2,3,4,5,6};
        symbols<char, int> sym(syms, data);

        int i;
        BOOST_TEST((test_attr("Joel", sym, i)));
        BOOST_TEST(i == 1);
        BOOST_TEST((test_attr("Ruby", sym, i)));
        BOOST_TEST(i == 2);
        BOOST_TEST((test_attr("Tenji", sym, i)));
        BOOST_TEST(i == 3);
        BOOST_TEST((test_attr("Tutit", sym, i)));
        BOOST_TEST(i == 4);
        BOOST_TEST((test_attr("Kim", sym, i)));
        BOOST_TEST(i == 5);
        BOOST_TEST((test_attr("Joey", sym, i)));
        BOOST_TEST(i == 6);
        BOOST_TEST((!test_attr("XXX", sym, i)));
    }

    return boost::report_errors();
}
int main()
{
    using spirit_test::test_attr;
    using spirit_test::test;
    using boost::spirit::qi::bool_;

    {
        BOOST_TEST(test("true", bool_));
        BOOST_TEST(test("false", bool_));
        BOOST_TEST(!test("fasle", bool_));
    }

    {
        using boost::spirit::qi::true_;
        using boost::spirit::qi::false_;

        BOOST_TEST(test("true", true_));
        BOOST_TEST(!test("true", false_));
        BOOST_TEST(test("false", false_));
        BOOST_TEST(!test("false", true_));
    }

    {
        using boost::spirit::qi::true_;
        using boost::spirit::qi::false_;
        using boost::spirit::qi::no_case;

        BOOST_TEST(test("True", no_case[bool_]));
        BOOST_TEST(test("False", no_case[bool_]));
        BOOST_TEST(test("True", no_case[true_]));
        BOOST_TEST(test("False", no_case[false_]));
    }

    {
        bool b = false;
        BOOST_TEST(test_attr("true", bool_, b) && b);
        BOOST_TEST(test_attr("false", bool_, b) && !b);
        BOOST_TEST(!test_attr("fasle", bool_, b));
    }

    {
        typedef boost::spirit::qi::bool_parser<bool, backwards_bool_policies> 
            backwards_bool_type;
        backwards_bool_type const backwards_bool = backwards_bool_type();

        BOOST_TEST(test("true", backwards_bool));
        BOOST_TEST(test("eurt", backwards_bool));
        BOOST_TEST(!test("false", backwards_bool));
        BOOST_TEST(!test("fasle", backwards_bool));

        bool b = false;
        BOOST_TEST(test_attr("true", backwards_bool, b) && b);
        BOOST_TEST(test_attr("eurt", backwards_bool, b) && !b);
        BOOST_TEST(!test_attr("false", backwards_bool, b));
        BOOST_TEST(!test_attr("fasle", backwards_bool, b));
    }

    {
        typedef boost::spirit::qi::bool_parser<test_bool_type> 
            bool_test_type;
        bool_test_type const test_bool = bool_test_type();

        BOOST_TEST(test("true", test_bool));
        BOOST_TEST(test("false", test_bool));
        BOOST_TEST(!test("fasle", test_bool));

        test_bool_type b = false;
        BOOST_TEST(test_attr("true", test_bool, b) && b.b);
        BOOST_TEST(test_attr("false", test_bool, b) && !b.b);
        BOOST_TEST(!test_attr("fasle", test_bool, b));
    }

    return boost::report_errors();
}
Example #8
0
int main()
{
    using spirit_test::test_attr;
    using spirit_test::test;

    using boost::spirit::qi::byte_;
    using boost::spirit::qi::word;
    using boost::spirit::qi::dword;
    using boost::spirit::qi::big_word;
    using boost::spirit::qi::big_dword;
    using boost::spirit::qi::little_word;
    using boost::spirit::qi::little_dword;
#ifdef BOOST_HAS_LONG_LONG
    using boost::spirit::qi::qword;
    using boost::spirit::qi::big_qword;
    using boost::spirit::qi::little_qword;
#endif

    boost::uint8_t uc;
    boost::uint16_t us;
    boost::uint32_t ui;
#ifdef BOOST_HAS_LONG_LONG
    boost::uint64_t ul;
#endif

    {   // test native endian binaries
#ifdef BOOST_LITTLE_ENDIAN
        BOOST_TEST(test_attr("\x01", byte_, uc) && uc == 0x01);
        BOOST_TEST(test_attr("\x01\x02", word, us) && us == 0x0201);
        BOOST_TEST(test_attr("\x01\x02\x03\x04", dword, ui) && ui == 0x04030201);
#ifdef BOOST_HAS_LONG_LONG
        BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", qword, ul) &&
                   ul == 0x0807060504030201LL);
#endif
#else
        BOOST_TEST(test_attr("\x01", byte_, uc) && uc == 0x01);
        BOOST_TEST(test_attr("\x01\x02", word, us) && us ==  0x0102);
        BOOST_TEST(test_attr("\x01\x02\x03\x04", dword, ui) && ui == 0x01020304);
#ifdef BOOST_HAS_LONG_LONG
        BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", qword, ul) &&
                   ul == 0x0102030405060708LL);
#endif
#endif
    }

    {   // test native endian binaries
#ifdef BOOST_LITTLE_ENDIAN
        BOOST_TEST(test("\x01", byte_(0x01)));
        BOOST_TEST(test("\x01\x02", word(0x0201)));
        BOOST_TEST(test("\x01\x02\x03\x04", dword(0x04030201)));
#ifdef BOOST_HAS_LONG_LONG
        BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
                        qword(0x0807060504030201LL)));
#endif
#else
        BOOST_TEST(test("\x01", byte_(0x01)));
        BOOST_TEST(test("\x01\x02", word(0x0102)));
        BOOST_TEST(test("\x01\x02\x03\x04", dword(0x01020304)));
#ifdef BOOST_HAS_LONG_LONG
        BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
                        qword(0x0102030405060708LL)));
#endif
#endif
    }

    {   // test big endian binaries
        BOOST_TEST(test_attr("\x01\x02", big_word, us) && us == 0x0102);
        BOOST_TEST(test_attr("\x01\x02\x03\x04", big_dword, ui) && ui == 0x01020304);
#ifdef BOOST_HAS_LONG_LONG
        BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", big_qword, ul)
                   && ul == 0x0102030405060708LL);
#endif
    }

    {
        BOOST_TEST(test("\x01\x02", big_word(0x0102)));
        BOOST_TEST(test("\x01\x02\x03\x04", big_dword(0x01020304)));
#ifdef BOOST_HAS_LONG_LONG
        BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
                        big_qword(0x0102030405060708LL)));
#endif
    }

    {   // test little endian binaries
        BOOST_TEST(test_attr("\x01\x02", little_word, us) && us == 0x0201);
        BOOST_TEST(test_attr("\x01\x02\x03\x04", little_dword, ui) && ui == 0x04030201);
#ifdef BOOST_HAS_LONG_LONG
        BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", little_qword, ul)
                   && ul == 0x0807060504030201LL);
#endif
    }

    {
        BOOST_TEST(test("\x01\x02", little_word(0x0201)));
        BOOST_TEST(test("\x01\x02\x03\x04", little_dword(0x04030201)));
#ifdef BOOST_HAS_LONG_LONG
        BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
                        little_qword(0x0807060504030201LL)));
#endif
    }

    return boost::report_errors();
}
Example #9
0
int
main()
{
    using spirit_test::test;
    using spirit_test::test_attr;

    {
        using namespace boost::spirit::ascii;
        BOOST_TEST(test("1", alnum));
        BOOST_TEST(!test(" ", alnum));
        BOOST_TEST(!test("1", alpha));
        BOOST_TEST(test("x", alpha));
        BOOST_TEST(test(" ", blank));
        BOOST_TEST(!test("x", blank));
        BOOST_TEST(test("1", digit));
        BOOST_TEST(!test("x", digit));
        BOOST_TEST(test("a", lower));
        BOOST_TEST(!test("A", lower));
        BOOST_TEST(test("!", punct));
        BOOST_TEST(!test("x", punct));
        BOOST_TEST(test(" ", space));
        BOOST_TEST(test("\n", space));
        BOOST_TEST(test("\r", space));
        BOOST_TEST(test("\t", space));
        BOOST_TEST(test("A", upper));
        BOOST_TEST(!test("a", upper));
        BOOST_TEST(test("A", xdigit));
        BOOST_TEST(test("0", xdigit));
        BOOST_TEST(test("f", xdigit));
        BOOST_TEST(!test("g", xdigit));

        // should fail, not assert!
        // $$$ Removing this test for now $$$
        // BOOST_TEST(!test("\265", space));
    }

    {
        using namespace boost::spirit::ascii;
        BOOST_TEST(!test("1", ~alnum));
        BOOST_TEST(test(" ", ~alnum));
        BOOST_TEST(test("1", ~alpha));
        BOOST_TEST(!test("x", ~alpha));
        BOOST_TEST(!test(" ", ~blank));
        BOOST_TEST(test("x", ~blank));
        BOOST_TEST(!test("1", ~digit));
        BOOST_TEST(test("x", ~digit));
        BOOST_TEST(!test("a", ~lower));
        BOOST_TEST(test("A", ~lower));
        BOOST_TEST(!test("!", ~punct));
        BOOST_TEST(test("x", ~punct));
        BOOST_TEST(!test(" ", ~space));
        BOOST_TEST(!test("\n", ~space));
        BOOST_TEST(!test("\r", ~space));
        BOOST_TEST(!test("\t", ~space));
        BOOST_TEST(!test("A", ~upper));
        BOOST_TEST(test("a", ~upper));
        BOOST_TEST(!test("A", ~xdigit));
        BOOST_TEST(!test("0", ~xdigit));
        BOOST_TEST(!test("f", ~xdigit));
        BOOST_TEST(test("g", ~xdigit));
    }

    {
        // we use the hoisted qi namespace this time
        using namespace boost::spirit::qi::iso8859_1;
        BOOST_TEST(test("1", alnum));
        BOOST_TEST(!test(" ", alnum));
        BOOST_TEST(!test("1", alpha));
        BOOST_TEST(test("x", alpha));
        BOOST_TEST(test(" ", blank));
        BOOST_TEST(!test("x", blank));
        BOOST_TEST(test("1", digit));
        BOOST_TEST(!test("x", digit));
        BOOST_TEST(test("a", lower));
        BOOST_TEST(!test("A", lower));
        BOOST_TEST(test("!", punct));
        BOOST_TEST(!test("x", punct));
        BOOST_TEST(test(" ", space));
        BOOST_TEST(test("\n", space));
        BOOST_TEST(test("\r", space));
        BOOST_TEST(test("\t", space));
        BOOST_TEST(test("A", upper));
        BOOST_TEST(!test("a", upper));
        BOOST_TEST(test("A", xdigit));
        BOOST_TEST(test("0", xdigit));
        BOOST_TEST(test("f", xdigit));
        BOOST_TEST(!test("g", xdigit));

        // test extended ASCII characters
        BOOST_TEST(test("\xE9", alpha));
        BOOST_TEST(test("\xE9", lower));
        BOOST_TEST(!test("\xE9", upper));
    }

    {
        using namespace boost::spirit::standard;
        BOOST_TEST(test("1", alnum));
        BOOST_TEST(!test(" ", alnum));
        BOOST_TEST(!test("1", alpha));
        BOOST_TEST(test("x", alpha));
        BOOST_TEST(test(" ", blank));
        BOOST_TEST(!test("x", blank));
        BOOST_TEST(test("1", digit));
        BOOST_TEST(!test("x", digit));
        BOOST_TEST(test("a", lower));
        BOOST_TEST(!test("A", lower));
        BOOST_TEST(test("!", punct));
        BOOST_TEST(!test("x", punct));
        BOOST_TEST(test(" ", space));
        BOOST_TEST(test("\n", space));
        BOOST_TEST(test("\r", space));
        BOOST_TEST(test("\t", space));
        BOOST_TEST(test("A", upper));
        BOOST_TEST(!test("a", upper));
        BOOST_TEST(test("A", xdigit));
        BOOST_TEST(test("0", xdigit));
        BOOST_TEST(test("f", xdigit));
        BOOST_TEST(!test("g", xdigit));
    }

    {
        using namespace boost::spirit::standard_wide;
        BOOST_TEST(test(L"1", alnum));
        BOOST_TEST(!test(L" ", alnum));
        BOOST_TEST(!test(L"1", alpha));
        BOOST_TEST(test(L"x", alpha));
        BOOST_TEST(test(L" ", blank));
        BOOST_TEST(!test(L"x", blank));
        BOOST_TEST(test(L"1", digit));
        BOOST_TEST(!test(L"x", digit));
        BOOST_TEST(test(L"a", lower));
        BOOST_TEST(!test(L"A", lower));
        BOOST_TEST(test(L"!", punct));
        BOOST_TEST(!test(L"x", punct));
        BOOST_TEST(test(L" ", space));
        BOOST_TEST(test(L"\n", space));
        BOOST_TEST(test(L"\r", space));
        BOOST_TEST(test(L"\t", space));
        BOOST_TEST(test(L"A", upper));
        BOOST_TEST(!test(L"a", upper));
        BOOST_TEST(test(L"A", xdigit));
        BOOST_TEST(test(L"0", xdigit));
        BOOST_TEST(test(L"f", xdigit));
        BOOST_TEST(!test(L"g", xdigit));
    }

    {
        using namespace boost::spirit::unicode;
        BOOST_TEST(test(L"1", alnum));
        BOOST_TEST(!test(L" ", alnum));
        BOOST_TEST(!test(L"1", alpha));
        BOOST_TEST(test(L"x", alpha));
        BOOST_TEST(test(L" ", blank));
        BOOST_TEST(!test(L"x", blank));
        BOOST_TEST(test(L"1", digit));
        BOOST_TEST(!test(L"x", digit));
        BOOST_TEST(test(L"a", lower));
        BOOST_TEST(!test(L"A", lower));
        BOOST_TEST(test(L"!", punct));
        BOOST_TEST(!test(L"x", punct));
        BOOST_TEST(test(L" ", space));
        BOOST_TEST(test(L"\n", space));
        BOOST_TEST(test(L"\r", space));
        BOOST_TEST(test(L"\t", space));
        BOOST_TEST(test(L"A", upper));
        BOOST_TEST(!test(L"a", upper));
        BOOST_TEST(test(L"A", xdigit));
        BOOST_TEST(test(L"0", xdigit));
        BOOST_TEST(test(L"f", xdigit));
        BOOST_TEST(!test(L"g", xdigit));

        // TODO: these tests are suspicious, they do not test unicode
        BOOST_TEST(test("\xE9", alpha));
        BOOST_TEST(test("\xE9", lower));
        BOOST_TEST(!test("\xE9", upper));
    }

    {   // test attribute extraction
        using boost::spirit::qi::domain;
        using boost::spirit::traits::attribute_of;
        using boost::spirit::iso8859_1::alpha;
        using boost::spirit::iso8859_1::alpha_type;
        using boost::spirit::result_of::compile;

        BOOST_STATIC_ASSERT((
            boost::is_same<
                attribute_of<compile<domain, alpha_type>::type>::type
              , unsigned char>::value));

        int attr = 0;
        BOOST_TEST(test_attr("a", alpha, attr));
        BOOST_TEST(attr == 'a');
    }

    {   // test attribute extraction
        using boost::spirit::iso8859_1::alpha;
        using boost::spirit::iso8859_1::space;
        char attr = 0;
        BOOST_TEST(test_attr("     a", alpha, attr, space));
        BOOST_TEST(attr == 'a');
    }

    {   // test action

        using namespace boost::spirit::ascii;
        using boost::phoenix::ref;
        using boost::spirit::_1;
        char ch;

        BOOST_TEST(test("x", alnum[ref(ch) = _1]));
        BOOST_TEST(ch == 'x');
        BOOST_TEST(test("   A", alnum[ref(ch) = _1], space));
        BOOST_TEST(ch == 'A');
    }

    return boost::report_errors();
}
Example #10
0
int
main()
{
    using spirit_test::test;
    using spirit_test::test_attr;
    ///////////////////////////////////////////////////////////////////////////
    //  parameterized unsigned tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::uint_;
        unsigned u;

        BOOST_TEST(test("123456", uint_(123456)));
        BOOST_TEST(!test("123456", uint_(654321)));
        BOOST_TEST(test_attr("123456", uint_(123456), u));
        BOOST_TEST(u == 123456);
        BOOST_TEST(!test_attr("123456", uint_(654321), u));

        BOOST_TEST(test(max_unsigned, uint_(UINT_MAX)));
        BOOST_TEST(test_attr(max_unsigned, uint_(UINT_MAX), u));
        BOOST_TEST(u == UINT_MAX);
    }

    ///////////////////////////////////////////////////////////////////////////
    //  parameterized binary tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::bin;
        unsigned u;

        BOOST_TEST(test("11111110", bin(0xFE)));
        BOOST_TEST(!test("11111110", bin(0xEF)));
        BOOST_TEST(test_attr("11111110", bin(0xFE), u));
        BOOST_TEST(u == 0xFE);
        BOOST_TEST(!test_attr("11111110", bin(0xEF), u));

        BOOST_TEST(test(max_binary, bin(UINT_MAX)));
        BOOST_TEST(test_attr(max_binary, bin(UINT_MAX), u));
        BOOST_TEST(u == UINT_MAX);
    }

    ///////////////////////////////////////////////////////////////////////////
    //  parameterized octal tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::oct;
        unsigned u;

        BOOST_TEST(test("12545674515", oct(012545674515)));
        BOOST_TEST(!test("12545674515", oct(051547654521)));
        BOOST_TEST(test_attr("12545674515", oct(012545674515), u));
        BOOST_TEST(u == 012545674515);
        BOOST_TEST(!test_attr("12545674515", oct(051547654521), u));

        BOOST_TEST(test(max_octal, oct(UINT_MAX)));
        BOOST_TEST(test_attr(max_octal, oct(UINT_MAX), u));
        BOOST_TEST(u == UINT_MAX);
    }

    ///////////////////////////////////////////////////////////////////////////
    //  parameterized hex tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::hex;
        unsigned u;

        BOOST_TEST(test("95BC8DF", hex(0x95BC8DF)));
        BOOST_TEST(!test("95BC8DF", hex(0xFD8CB59)));
        BOOST_TEST(test_attr("95BC8DF", hex(0x95BC8DF), u));
        BOOST_TEST(u == 0x95BC8DF);
        BOOST_TEST(!test_attr("95BC8DF", hex(0xFD8CB59), u));

        BOOST_TEST(test("abcdef12", hex(0xabcdef12)));
        BOOST_TEST(!test("abcdef12", hex(0x12fedcba)));
        BOOST_TEST(test_attr("abcdef12", hex(0xabcdef12), u));
        BOOST_TEST(u == 0xabcdef12);
        BOOST_TEST(!test_attr("abcdef12", hex(0x12fedcba), u));

        BOOST_TEST(test(max_hex, hex(UINT_MAX)));
        BOOST_TEST(test_attr(max_hex, hex(UINT_MAX), u));
        BOOST_TEST(u == UINT_MAX);
    }

    ///////////////////////////////////////////////////////////////////////////
    //  parameterized action tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::phoenix::ref;
        using boost::spirit::ascii::space;
        using boost::spirit::qi::uint_;
        using boost::spirit::qi::_1;
        unsigned n, m;

        BOOST_TEST(test("123", uint_(123)[ref(n) = _1]));
        BOOST_TEST(n == 123);
        BOOST_TEST(!test("123", uint_(321)[ref(n) = _1]));
        
        BOOST_TEST(test_attr("789", uint_(789)[ref(n) = _1], m));
        BOOST_TEST(n == 789 && m == 789);
        BOOST_TEST(!test_attr("789", uint_(987)[ref(n) = _1], m));

        BOOST_TEST(test("   456", uint_(456)[ref(n) = _1], space));
        BOOST_TEST(n == 456);
        BOOST_TEST(!test("   456", uint_(654)[ref(n) = _1], space));
    }
    
    ///////////////////////////////////////////////////////////////////////////
    //  parameterized lazy tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::phoenix::ref;
        using boost::spirit::qi::uint_;
        unsigned n = 123, m = 321;

        BOOST_TEST(test("123", uint_(ref(n))));
        BOOST_TEST(!test("123", uint_(ref(m))));
    }

    ///////////////////////////////////////////////////////////////////////////
    //  parameterized custom uint tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::uint_;
        using boost::spirit::qi::uint_parser;
        custom_uint u;

        BOOST_TEST(test_attr("123456", uint_(123456), u));
        uint_parser<custom_uint, 10, 1, 2> uint2;
        BOOST_TEST(test_attr("12", uint2(12), u));
    }

    return boost::report_errors();
}
Example #11
0
int
main()
{
    using spirit_test::test;
    using spirit_test::test_attr;
    ///////////////////////////////////////////////////////////////////////////
    //  signed real number tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::double_;
        using boost::spirit::qi::float_;
        using boost::spirit::qi::parse;
        double  d;
        float f;

        BOOST_TEST(test("-1234", double_));
        BOOST_TEST(test_attr("-1234", double_, d) && compare(d, -1234));

        BOOST_TEST(test("-1.2e3", double_));
        BOOST_TEST(test_attr("-1.2e3", double_, d) && compare(d, -1.2e3));

        BOOST_TEST(test("+1.2e3", double_));
        BOOST_TEST(test_attr("+1.2e3", double_, d) && compare(d, 1.2e3));

        BOOST_TEST(test("-0.1", double_));
        BOOST_TEST(test_attr("-0.1", double_, d) && compare(d, -0.1));

        BOOST_TEST(test("-1.2e-3", double_));
        BOOST_TEST(test_attr("-1.2e-3", double_, d) && compare(d, -1.2e-3));

        BOOST_TEST(test("-1.e2", double_));
        BOOST_TEST(test_attr("-1.e2", double_, d) && compare(d, -1.e2));

        BOOST_TEST(test("-.2e3", double_));
        BOOST_TEST(test_attr("-.2e3", double_, d) && compare(d, -.2e3));

        BOOST_TEST(test("-2e3", double_));
        BOOST_TEST(test_attr("-2e3", double_, d) && compare(d, -2e3));

        BOOST_TEST(!test("-e3", double_));
        BOOST_TEST(!test_attr("-e3", double_, d));

        BOOST_TEST(!test("-1.2e", double_));
        BOOST_TEST(!test_attr("-1.2e", double_, d));

        BOOST_TEST(test_attr("-5.7222349715140557e+307", double_, d));
        BOOST_TEST(d == -5.7222349715140557e+307); // exact!

        BOOST_TEST(test_attr("2.0332938517515416e-308", double_, d));
        BOOST_TEST(d == 2.0332938517515416e-308); // exact!

        BOOST_TEST(test_attr("20332938517515416e291", double_, d));
        BOOST_TEST(d == 20332938517515416e291); // exact!

        BOOST_TEST(test_attr("2.0332938517515416e307", double_, d));
        BOOST_TEST(d == 2.0332938517515416e307); // exact!

        BOOST_TEST(test_attr("1.7976931348623157e+308", double_, d));   // DBL_MAX
        BOOST_TEST(d == 1.7976931348623157e+308); // exact!

        BOOST_TEST(test_attr("2.2204460492503131e-16", double_, d));    // DBL_EPSILON
        BOOST_TEST(d == 2.2204460492503131e-16); // exact!

        BOOST_TEST(test_attr("2.2250738585072014e-308", double_, d));   // DBL_MIN
        BOOST_TEST(d == 2.2250738585072014e-308); // exact!

        BOOST_TEST(test_attr("4.9406564584124654e-324", double_, d));   // DBL_DENORM_MIN
        BOOST_TEST(d == 4.9406564584124654e-324); // exact!

        BOOST_TEST(test_attr("219721.03839999999", double_, d));
        BOOST_TEST(d == 219721.03839999999); // exact!

        BOOST_TEST(test_attr("-5.7222349715140557e+307", double_, d));
        BOOST_TEST(d == -5.7222349715140557e+307); // exact!

        BOOST_TEST(test_attr("2.2204460492503131e-16", double_, d));
        BOOST_TEST(d == 2.2204460492503131e-16); // exact!

        // floats...

        BOOST_TEST(test_attr("3.402823466e+38", float_, f));            // FLT_MAX
        BOOST_TEST(f == 3.402823466e+38F); // exact!

        BOOST_TEST(test_attr("1.192092896e-07", float_, f));            // FLT_EPSILON
        BOOST_TEST(f == 1.192092896e-07F); // exact!

        BOOST_TEST(test_attr("1.175494351e-38", float_, f));            // FLT_MIN
        BOOST_TEST(f == 1.175494351e-38F); // exact!

        BOOST_TEST(test_attr("219721.03839999999", float_, f));
        BOOST_TEST(f == 219721.03839999999f); // inexact

        BOOST_TEST(test_attr("2.2204460492503131e-16", float_, f));
        BOOST_TEST(f == 2.2204460492503131e-16f); // inexact

        // big exponents!
        // fail, but do not assert!
        BOOST_TEST(!test_attr("123e1234000000", double_, d));
        BOOST_TEST(!test_attr("123e-1234000000", double_, d));

        using boost::math::fpclassify;
        using boost::spirit::detail::signbit;   // Boost version is broken

        BOOST_TEST(test("-inf", double_));
        BOOST_TEST(test("-infinity", double_));
        BOOST_TEST(test_attr("-inf", double_, d) &&
            FP_INFINITE == fpclassify(d) && signbit(d));
        BOOST_TEST(test_attr("-infinity", double_, d) &&
            FP_INFINITE == fpclassify(d) && signbit(d));
        BOOST_TEST(test("-INF", double_));
        BOOST_TEST(test("-INFINITY", double_));
        BOOST_TEST(test_attr("-INF", double_, d) &&
            FP_INFINITE == fpclassify(d) && signbit(d));
        BOOST_TEST(test_attr("-INFINITY", double_, d) &&
            FP_INFINITE == fpclassify(d) && signbit(d));

        BOOST_TEST(test("-nan", double_));
        BOOST_TEST(test_attr("-nan", double_, d) &&
            FP_NAN == fpclassify(d) && signbit(d));
        BOOST_TEST(test("-NAN", double_));
        BOOST_TEST(test_attr("-NAN", double_, d) &&
            FP_NAN == fpclassify(d) && signbit(d));

        BOOST_TEST(test("-nan(...)", double_));
        BOOST_TEST(test_attr("-nan(...)", double_, d) &&
            FP_NAN == fpclassify(d) && signbit(d));
        BOOST_TEST(test("-NAN(...)", double_));
        BOOST_TEST(test_attr("-NAN(...)", double_, d) &&
            FP_NAN == fpclassify(d) && signbit(d));
    }

    return boost::report_errors();
}
Example #12
0
int main()
{
    using spirit_test::test;
    using spirit_test::test_delimited;
    using boost::spirit::utree;
    using boost::spirit::utree_type;
    using boost::spirit::utf8_string_range_type;
    using boost::spirit::utf8_string_type;
    using boost::spirit::utf8_symbol_type;

    using boost::spirit::karma::char_;
    using boost::spirit::karma::bool_;
    using boost::spirit::karma::int_;
    using boost::spirit::karma::double_;
    using boost::spirit::karma::string;
    using boost::spirit::karma::space;
    using boost::spirit::karma::rule;

    typedef spirit_test::output_iterator<char>::type output_iterator;

    // primitive data types
    {
        utree ut('x');
        BOOST_TEST(test("x", char_, ut));

        ut = false;
        BOOST_TEST(test("false", bool_, ut));

        ut = 123;
        BOOST_TEST(test("123", int_, ut));

        ut = 123.45;
        BOOST_TEST(test("123.45", double_, ut));

        ut = "abc";
        BOOST_TEST(test("abc", string, ut));

        ut = utf8_symbol_type("xyz");
        BOOST_TEST(test("xyz", string, ut));
    }

    // sequences
    {
        using boost::spirit::karma::digit;
        using boost::spirit::karma::repeat;

        utree ut;
        ut.push_back('x');
        ut.push_back('y');
        BOOST_TEST(test("xy", char_ << char_, ut));

        ut.clear();
        ut.push_back(123);
        ut.push_back(456);
        BOOST_TEST(test_delimited("123 456 ", int_ << int_, ut, space));

        ut.clear();
        ut.push_back(1.23);
        ut.push_back(4.56);
        BOOST_TEST(test_delimited("1.23 4.56 ", double_ << double_, ut, space));

        ut.clear();
        ut.push_back(1.23);
        ut.push_back("ab");
        BOOST_TEST(test("1.23ab", double_ << string, ut));

        ut.clear();

        rule<output_iterator, double()> r1 = double_;
        rule<output_iterator, utree()> r2 = double_;

        // ( 1.23 "a" "b" )
        ut.push_back(1.23);
        ut.push_back('a');
        ut.push_back('b');
        BOOST_TEST(test("1.23ab", double_ << *char_, ut));
        BOOST_TEST(test("1.23ab", r1 << *char_, ut)); 
        BOOST_TEST(test("1.23ab", r2 << *char_, ut)); 

        // ( ( 1.23 ) "a" "b" )
        ut.clear();
        utree ut1;
        ut1.push_back(1.23);
        ut.push_back(ut1);
        ut.push_back('a');
        ut.push_back('b');
        BOOST_TEST(test("1.23ab", r1 << *char_, ut)); 
        BOOST_TEST(test("1.23ab", r2 << *char_, ut)); 

        // ( "a" "b" 1.23 )
        ut.clear();
        ut.push_back('a');
        ut.push_back('b');
        ut.push_back(1.23);
        BOOST_TEST(test("ab1.23", repeat(2)[~digit] << double_, ut));
        BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r1, ut));
        BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r2, ut));

        // ( "a" "b" ( 1.23 ) )
        ut.clear();
        ut.push_back('a');
        ut.push_back('b');
        ut.push_back(ut1);
        BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r1, ut));
        BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r2, ut));
    }

    return boost::report_errors();
}
Example #13
0
int
main()
{
    using spirit_test::test;
    using spirit_test::test_attr;

    ///////////////////////////////////////////////////////////////////////////
    //  signed integer tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::x3::int_;
        int i;

        BOOST_TEST(test("123456", int_));
        BOOST_TEST(test_attr("123456", int_, i));
        BOOST_TEST(i == 123456);

        BOOST_TEST(test("+123456", int_));
        BOOST_TEST(test_attr("+123456", int_, i));
        BOOST_TEST(i == 123456);

        BOOST_TEST(test("-123456", int_));
        BOOST_TEST(test_attr("-123456", int_, i));
        BOOST_TEST(i == -123456);

        BOOST_TEST(test(max_int, int_));
        BOOST_TEST(test_attr(max_int, int_, i));
        BOOST_TEST(i == INT_MAX);

        BOOST_TEST(test(min_int, int_));
        BOOST_TEST(test_attr(min_int, int_, i));
        BOOST_TEST(i == INT_MIN);

        BOOST_TEST(!test(int_overflow, int_));
        BOOST_TEST(!test_attr(int_overflow, int_, i));
        BOOST_TEST(!test(int_underflow, int_));
        BOOST_TEST(!test_attr(int_underflow, int_, i));

        BOOST_TEST(!test("-", int_));
        BOOST_TEST(!test_attr("-", int_, i));

        BOOST_TEST(!test("+", int_));
        BOOST_TEST(!test_attr("+", int_, i));

        // Bug report from Steve Nutt
        BOOST_TEST(!test_attr("5368709120", int_, i));

        // with leading zeros
        BOOST_TEST(test("0000000000123456", int_));
        BOOST_TEST(test_attr("0000000000123456", int_, i));
        BOOST_TEST(i == 123456);
    }

    ///////////////////////////////////////////////////////////////////////////
    //  long long tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::x3::long_long;
        boost::long_long_type ll;

        BOOST_TEST(test("1234567890123456789", long_long));
        BOOST_TEST(test_attr("1234567890123456789", long_long, ll));
        BOOST_TEST(ll == 1234567890123456789LL);

        BOOST_TEST(test("-1234567890123456789", long_long));
        BOOST_TEST(test_attr("-1234567890123456789", long_long, ll));
        BOOST_TEST(ll == -1234567890123456789LL);

        BOOST_TEST(test(max_long_long, long_long));
        BOOST_TEST(test_attr(max_long_long, long_long, ll));
        BOOST_TEST(ll == LLONG_MAX);

        BOOST_TEST(test(min_long_long, long_long));
        BOOST_TEST(test_attr(min_long_long, long_long, ll));
        BOOST_TEST(ll == LLONG_MIN);

        BOOST_TEST(!test(long_long_overflow, long_long));
        BOOST_TEST(!test_attr(long_long_overflow, long_long, ll));
        BOOST_TEST(!test(long_long_underflow, long_long));
        BOOST_TEST(!test_attr(long_long_underflow, long_long, ll));
    }

    ///////////////////////////////////////////////////////////////////////////
    //  short_ and long_ tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::x3::short_;
        using boost::spirit::x3::long_;
        int i;

        BOOST_TEST(test("12345", short_));
        BOOST_TEST(test_attr("12345", short_, i));
        BOOST_TEST(i == 12345);

        BOOST_TEST(test("1234567890", long_));
        BOOST_TEST(test_attr("1234567890", long_, i));
        BOOST_TEST(i == 1234567890);
    }

    ///////////////////////////////////////////////////////////////////////////
    // Check overflow is parse error
    ///////////////////////////////////////////////////////////////////////////
    {
        boost::spirit::x3::int_parser<boost::int8_t> int8_;
        char c;

        BOOST_TEST(!test_attr("999", int8_, c));

        int i;
        using boost::spirit::x3::short_;
        BOOST_TEST(!test_attr("32769", short_, i, false));
        BOOST_TEST(!test_attr("41234", short_, i, false));
    }

    ///////////////////////////////////////////////////////////////////////////
    //  int_parser<unused_type> tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::x3::int_parser;
        using boost::spirit::x3::unused_type;
        int_parser<unused_type> any_int;

        BOOST_TEST(test("123456", any_int));
        BOOST_TEST(test("-123456", any_int));
        BOOST_TEST(test("-1234567890123456789", any_int));
    }

    // $$$ Not yet implemented $$$
    //~ ///////////////////////////////////////////////////////////////////////////
    //~ //  action tests
    //~ ///////////////////////////////////////////////////////////////////////////
    //~ {
        //~ using boost::phoenix::ref;
        //~ using boost::spirit::x3::_1;
        //~ using boost::spirit::x3::ascii::space;
        //~ using boost::spirit::x3::int_;
        //~ int n, m;

        //~ BOOST_TEST(test("123", int_[ref(n) = _1]));
        //~ BOOST_TEST(n == 123);
        //~ BOOST_TEST(test_attr("789", int_[ref(n) = _1], m));
        //~ BOOST_TEST(n == 789 && m == 789);
        //~ BOOST_TEST(test("   456", int_[ref(n) = _1], space));
        //~ BOOST_TEST(n == 456);
    //~ }

    ///////////////////////////////////////////////////////////////////////////
    //  custom int tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::x3::int_;
        using boost::spirit::x3::int_parser;
        custom_int i;

        BOOST_TEST(test_attr("-123456", int_, i));
        int_parser<custom_int, 10, 1, 2> int2;
        BOOST_TEST(test_attr("-12", int2, i));
    }

    ///////////////////////////////////////////////////////////////////////////
    //  single-element fusion vector tests
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::x3::int_;
        using boost::spirit::x3::int_parser;
        boost::fusion::vector<int> i;

        BOOST_TEST(test_attr("-123456", int_, i));
        BOOST_TEST(boost::fusion::at_c<0>(i) == -123456);
    }

    return boost::report_errors();
}
Example #14
0
int
main()
{
    using spirit_test::test;
    using spirit_test::test_attr;

    ///////////////////////////////////////////////////////////////////////////////
    //  thousand separated numbers
    ///////////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::uint_parser;
        using boost::spirit::qi::parse;

        uint_parser<unsigned, 10, 1, 3> uint3;
        uint_parser<unsigned, 10, 3, 3> uint3_3;

    #define r (uint3 >> *(',' >> uint3_3))

        BOOST_TEST(test("1,234,567,890", r));
        BOOST_TEST(test("12,345,678,900", r));
        BOOST_TEST(test("123,456,789,000", r));
        BOOST_TEST(!test("1000,234,567,890", r));
        BOOST_TEST(!test("1,234,56,890", r));
        BOOST_TEST(!test("1,66", r));
    }

    ///////////////////////////////////////////////////////////////////////////////
    //  unsigned real number tests
    ///////////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::real_parser;
        using boost::spirit::qi::parse;
        using boost::spirit::qi::ureal_policies;

        real_parser<double, ureal_policies<double> > udouble;
        double  d;

        BOOST_TEST(test("1234", udouble));
        BOOST_TEST(test_attr("1234", udouble, d) && compare(d, 1234));

        BOOST_TEST(test("1.2e3", udouble));
        BOOST_TEST(test_attr("1.2e3", udouble, d) && compare(d, 1.2e3));

        BOOST_TEST(test("1.2e-3", udouble));
        BOOST_TEST(test_attr("1.2e-3", udouble, d) && compare(d, 1.2e-3));

        BOOST_TEST(test("1.e2", udouble));
        BOOST_TEST(test_attr("1.e2", udouble, d) && compare(d, 1.e2));

        BOOST_TEST(test("1.", udouble));
        BOOST_TEST(test_attr("1.", udouble, d) && compare(d, 1.));

        BOOST_TEST(test(".2e3", udouble));
        BOOST_TEST(test_attr(".2e3", udouble, d) && compare(d, .2e3));

        BOOST_TEST(test("2e3", udouble));
        BOOST_TEST(test_attr("2e3", udouble, d) && compare(d, 2e3));

        BOOST_TEST(test("2", udouble));
        BOOST_TEST(test_attr("2", udouble, d) && compare(d, 2));

        using boost::math::fpclassify;
        BOOST_TEST(test("inf", udouble));
        BOOST_TEST(test("infinity", udouble));
        BOOST_TEST(test("INF", udouble));
        BOOST_TEST(test("INFINITY", udouble));
        BOOST_TEST(test_attr("inf", udouble, d) && FP_INFINITE == fpclassify(d));
        BOOST_TEST(test_attr("INF", udouble, d) && FP_INFINITE == fpclassify(d));
        BOOST_TEST(test_attr("infinity", udouble, d) && FP_INFINITE == fpclassify(d));
        BOOST_TEST(test_attr("INFINITY", udouble, d) && FP_INFINITE == fpclassify(d));

        BOOST_TEST(test("nan", udouble));
        BOOST_TEST(test_attr("nan", udouble, d) && FP_NAN == fpclassify(d));
        BOOST_TEST(test("NAN", udouble));
        BOOST_TEST(test_attr("NAN", udouble, d) && FP_NAN == fpclassify(d));

        BOOST_TEST(test("nan(...)", udouble));
        BOOST_TEST(test_attr("nan(...)", udouble, d) && FP_NAN == fpclassify(d));
        BOOST_TEST(test("NAN(...)", udouble));
        BOOST_TEST(test_attr("NAN(...)", udouble, d) && FP_NAN == fpclassify(d));

        BOOST_TEST(!test("e3", udouble));
        BOOST_TEST(!test_attr("e3", udouble, d));

        BOOST_TEST(!test("-1.2e3", udouble));
        BOOST_TEST(!test_attr("-1.2e3", udouble, d));

        BOOST_TEST(!test("+1.2e3", udouble));
        BOOST_TEST(!test_attr("+1.2e3", udouble, d));

        BOOST_TEST(!test("1.2e", udouble));
        BOOST_TEST(!test_attr("1.2e", udouble, d));

        BOOST_TEST(!test("-.3", udouble));
        BOOST_TEST(!test_attr("-.3", udouble, d));
    }

///////////////////////////////////////////////////////////////////////////////
//  signed real number tests
///////////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::double_;
        using boost::spirit::qi::parse;
        double  d;

        BOOST_TEST(test("-1234", double_));
        BOOST_TEST(test_attr("-1234", double_, d) && compare(d, -1234));

        BOOST_TEST(test("-1.2e3", double_));
        BOOST_TEST(test_attr("-1.2e3", double_, d) && compare(d, -1.2e3));

        BOOST_TEST(test("+1.2e3", double_));
        BOOST_TEST(test_attr("+1.2e3", double_, d) && compare(d, 1.2e3));

        BOOST_TEST(test("-0.1", double_));
        BOOST_TEST(test_attr("-0.1", double_, d) && compare(d, -0.1));

        BOOST_TEST(test("-1.2e-3", double_));
        BOOST_TEST(test_attr("-1.2e-3", double_, d) && compare(d, -1.2e-3));

        BOOST_TEST(test("-1.e2", double_));
        BOOST_TEST(test_attr("-1.e2", double_, d) && compare(d, -1.e2));

        BOOST_TEST(test("-.2e3", double_));
        BOOST_TEST(test_attr("-.2e3", double_, d) && compare(d, -.2e3));

        BOOST_TEST(test("-2e3", double_));
        BOOST_TEST(test_attr("-2e3", double_, d) && compare(d, -2e3));

        BOOST_TEST(!test("-e3", double_));
        BOOST_TEST(!test_attr("-e3", double_, d));

        BOOST_TEST(!test("-1.2e", double_));
        BOOST_TEST(!test_attr("-1.2e", double_, d));

// this appears to be broken on Apple Tiger x86 with gcc4.0.1
#if defined(BOOST_SPIRIT_TEST_REAL_PRECISION)
        BOOST_TEST(test_attr("-5.7222349715140557e+307", double_, d));
        BOOST_TEST(d == -5.7222349715140557e+307); // exact!

        BOOST_TEST(test_attr("2.0332938517515416e-308", double_, d));
        BOOST_TEST(d == 2.0332938517515416e-308); // exact!

        BOOST_TEST(test_attr("20332938517515416e291", double_, d));
        BOOST_TEST(d == 20332938517515416e291); // exact!

        BOOST_TEST(test_attr("2.0332938517515416e307", double_, d));
        BOOST_TEST(d == 2.0332938517515416e307); // exact!
#endif

        using boost::math::fpclassify;
        using boost::spirit::detail::signbit;   // Boost version is broken

        BOOST_TEST(test("-inf", double_));
        BOOST_TEST(test("-infinity", double_));
        BOOST_TEST(test_attr("-inf", double_, d) &&
            FP_INFINITE == fpclassify(d) && signbit(d));
        BOOST_TEST(test_attr("-infinity", double_, d) &&
            FP_INFINITE == fpclassify(d) && signbit(d));
        BOOST_TEST(test("-INF", double_));
        BOOST_TEST(test("-INFINITY", double_));
        BOOST_TEST(test_attr("-INF", double_, d) &&
            FP_INFINITE == fpclassify(d) && signbit(d));
        BOOST_TEST(test_attr("-INFINITY", double_, d) &&
            FP_INFINITE == fpclassify(d) && signbit(d));

        BOOST_TEST(test("-nan", double_));
        BOOST_TEST(test_attr("-nan", double_, d) &&
            FP_NAN == fpclassify(d) && signbit(d));
        BOOST_TEST(test("-NAN", double_));
        BOOST_TEST(test_attr("-NAN", double_, d) &&
            FP_NAN == fpclassify(d) && signbit(d));

        BOOST_TEST(test("-nan(...)", double_));
        BOOST_TEST(test_attr("-nan(...)", double_, d) &&
            FP_NAN == fpclassify(d) && signbit(d));
        BOOST_TEST(test("-NAN(...)", double_));
        BOOST_TEST(test_attr("-NAN(...)", double_, d) &&
            FP_NAN == fpclassify(d) && signbit(d));
    }

    ///////////////////////////////////////////////////////////////////////////////
    //  strict real number tests
    ///////////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::real_parser;
        using boost::spirit::qi::parse;
        using boost::spirit::qi::strict_ureal_policies;
        using boost::spirit::qi::strict_real_policies;

        real_parser<double, strict_ureal_policies<double> > strict_udouble;
        real_parser<double, strict_real_policies<double> > strict_double;
        double  d;

        BOOST_TEST(!test("1234", strict_udouble));
        BOOST_TEST(!test_attr("1234", strict_udouble, d));

        BOOST_TEST(test("1.2", strict_udouble));
        BOOST_TEST(test_attr("1.2", strict_udouble, d) && compare(d, 1.2));

        BOOST_TEST(!test("-1234", strict_double));
        BOOST_TEST(!test_attr("-1234", strict_double, d));

        BOOST_TEST(test("123.", strict_double));
        BOOST_TEST(test_attr("123.", strict_double, d) && compare(d, 123));

        BOOST_TEST(test("3.E6", strict_double));
        BOOST_TEST(test_attr("3.E6", strict_double, d) && compare(d, 3e6));

        real_parser<double, no_trailing_dot_policy<double> > notrdot_real;
        real_parser<double, no_leading_dot_policy<double> > nolddot_real;

        BOOST_TEST(!test("1234.", notrdot_real));          //  Bad trailing dot
        BOOST_TEST(!test(".1234", nolddot_real));          //  Bad leading dot
    }

    ///////////////////////////////////////////////////////////////////////////
    //  Special thousands separated numbers
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::spirit::qi::real_parser;
        using boost::spirit::qi::parse;
        real_parser<double, ts_real_policies<double> > ts_real;
        double  d;

        BOOST_TEST(test("123,456,789.01", ts_real));
        BOOST_TEST(test_attr("123,456,789.01", ts_real, d) && compare(d, 123456789.01));

        BOOST_TEST(test("12,345,678.90", ts_real));
        BOOST_TEST(test_attr("12,345,678.90", ts_real, d) && compare(d, 12345678.90));

        BOOST_TEST(test("1,234,567.89", ts_real));
        BOOST_TEST(test_attr("1,234,567.89", ts_real, d) && compare(d, 1234567.89));

        BOOST_TEST(!test("1234,567,890", ts_real));
        BOOST_TEST(!test("1,234,5678,9", ts_real));
        BOOST_TEST(!test("1,234,567.89e6", ts_real));
        BOOST_TEST(!test("1,66", ts_real));
    }

    ///////////////////////////////////////////////////////////////////////////
    //  Custom data type
    ///////////////////////////////////////////////////////////////////////////
    {
        using boost::math::concepts::real_concept;
        using boost::spirit::qi::real_parser;
        using boost::spirit::qi::real_policies;
        using boost::spirit::qi::parse;

        real_parser<real_concept, real_policies<real_concept> > custom_real;
        real_concept d;

        BOOST_TEST(test("-1234", custom_real));
        BOOST_TEST(test_attr("-1234", custom_real, d) && compare(d, -1234));

        BOOST_TEST(test("-1.2e3", custom_real));
        BOOST_TEST(test_attr("-1.2e3", custom_real, d) && compare(d, -1.2e3));

        BOOST_TEST(test("+1.2e3", custom_real));
        BOOST_TEST(test_attr("+1.2e3", custom_real, d) && compare(d, 1.2e3));

        BOOST_TEST(test("-0.1", custom_real));
        BOOST_TEST(test_attr("-0.1", custom_real, d) && compare(d, -0.1));

        BOOST_TEST(test("-1.2e-3", custom_real));
        BOOST_TEST(test_attr("-1.2e-3", custom_real, d) && compare(d, -1.2e-3));

        BOOST_TEST(test("-1.e2", custom_real));
        BOOST_TEST(test_attr("-1.e2", custom_real, d) && compare(d, -1.e2));

        BOOST_TEST(test("-.2e3", custom_real));
        BOOST_TEST(test_attr("-.2e3", custom_real, d) && compare(d, -.2e3));

        BOOST_TEST(test("-2e3", custom_real));
        BOOST_TEST(test_attr("-2e3", custom_real, d) && compare(d, -2e3));

        BOOST_TEST(!test("-e3", custom_real));
        BOOST_TEST(!test_attr("-e3", custom_real, d));

        BOOST_TEST(!test("-1.2e", custom_real));
        BOOST_TEST(!test_attr("-1.2e", custom_real, d));
    }
    
    ///////////////////////////////////////////////////////////////////////////
    //  custom real tests
    ///////////////////////////////////////////////////////////////////////////
    //~ {
        //~ using boost::spirit::qi::double_;
        //~ custom_real n;

        //~ BOOST_TEST(test_attr("-123456e6", double_, n));
    //~ }

    return boost::report_errors();
}