1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 #include <string>
8 #include <vector>
9
10 #include <boost/detail/lightweight_test.hpp>
11
12 #include <boost/spirit/include/qi_operator.hpp>
13 #include <boost/spirit/include/qi_char.hpp>
14 #include <boost/spirit/include/qi_string.hpp>
15 #include <boost/spirit/include/qi_numeric.hpp>
16 #include <boost/spirit/include/qi_directive.hpp>
17 #include <boost/spirit/include/qi_action.hpp>
18 #include <boost/spirit/include/support_argument.hpp>
19 #include <boost/spirit/include/phoenix_core.hpp>
20 #include <boost/spirit/include/phoenix_operator.hpp>
21
22 #include <string>
23 #include <iostream>
24 #include "test.hpp"
25
26 struct x_attr
27 {
28 };
29
30 namespace boost { namespace spirit { namespace traits
31 {
32 template <>
33 struct container_value<x_attr>
34 {
35 typedef char type; // value type of container
36 };
37
38 template <>
39 struct push_back_container<x_attr, char>
40 {
callboost::spirit::traits::push_back_container41 static bool call(x_attr& /*c*/, char /*val*/)
42 {
43 // push back value type into container
44 return true;
45 }
46 };
47 }}}
48
49 int
main()50 main()
51 {
52 using spirit_test::test;
53 using spirit_test::test_attr;
54 using namespace boost::spirit::ascii;
55 using boost::spirit::qi::omit;
56 using boost::spirit::qi::uint_;
57 using boost::spirit::qi::int_;
58 using boost::spirit::qi::lexeme;
59
60 {
61 BOOST_TEST(test("aaaaaaaa", *char_));
62 BOOST_TEST(test("a", *char_));
63 BOOST_TEST(test("", *char_));
64 BOOST_TEST(test("aaaaaaaa", *alpha));
65 BOOST_TEST(!test("aaaaaaaa", *upper));
66 }
67
68 {
69 BOOST_TEST(test(" a a aaa aa", *char_, space));
70 BOOST_TEST(test("12345 678 9", *digit, space));
71 }
72
73 {
74 BOOST_TEST(test("aBcdeFGH", no_case[*char_]));
75 BOOST_TEST(test("a B cde FGH", no_case[*char_], space));
76 }
77
78 {
79 BOOST_TEST(test("12345 678 955 987", *uint_, space));
80 BOOST_TEST(test("12345, 678, 955, 987", uint_ >> *(',' >> uint_), space));
81 }
82
83 {
84 std::string s;
85 BOOST_TEST(test_attr("bbbb", *char_, s) && 4 == s.size() && s == "bbbb");
86
87 s.clear();
88 BOOST_TEST(test_attr("b b b b ", *char_, s, space) && s == "bbbb");
89
90 // The following 2 tests show that omit does not inhibit explicit attributes
91 s.clear();
92 BOOST_TEST(test_attr("bbbb", omit[*char_('b')], s) && s == "bbbb");
93
94 s.clear();
95 BOOST_TEST(test_attr("b b b b", omit[*char_('b')], s, space) && s == "bbbb");
96 }
97
98 {
99 std::vector<int> v;
100 BOOST_TEST(test_attr("123 456 789 10", *int_, v, space) && 4 == v.size() &&
101 v[0] == 123 && v[1] == 456 && v[2] == 789 && v[3] == 10);
102 }
103
104 {
105 std::vector<std::string> v;
106 BOOST_TEST(test_attr("a b c d", *lexeme[+alpha], v, space) && 4 == v.size() &&
107 v[0] == "a" && v[1] == "b" && v[2] == "c" && v[3] == "d");
108 }
109
110 {
111 std::vector<int> v;
112 BOOST_TEST(test_attr("123 456 789", *int_, v, space) && 3 == v.size() &&
113 v[0] == 123 && v[1] == 456 && v[2] == 789);
114 }
115
116 { // actions
117 namespace phx = boost::phoenix;
118 using boost::spirit::_1;
119
120 std::vector<char> v;
121 BOOST_TEST(test("bbbb", (*char_)[phx::ref(v) = _1]) && 4 == v.size() &&
122 v[0] == 'b' && v[1] == 'b' && v[2] == 'b' && v[3] == 'b');
123 }
124
125 { // more actions
126 namespace phx = boost::phoenix;
127 using boost::spirit::_1;
128
129 std::vector<int> v;
130 BOOST_TEST(test("123 456 789", (*int_)[phx::ref(v) = _1], space) && 3 == v.size() &&
131 v[0] == 123 && v[1] == 456 && v[2] == 789);
132 }
133
134 { // attribute customization
135
136 x_attr x;
137 test_attr("abcde", *char_, x);
138 }
139
140 return boost::report_errors();
141 }
142
143