1 /*=============================================================================
2 Copyright (c) 2001-2010 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 <boost/detail/lightweight_test.hpp>
8 #include <boost/spirit/include/qi_operator.hpp>
9 #include <boost/spirit/include/qi_char.hpp>
10 #include <boost/spirit/include/qi_string.hpp>
11 #include <boost/spirit/include/qi_numeric.hpp>
12 #include <boost/spirit/include/qi_action.hpp>
13 #include <boost/spirit/include/qi_nonterminal.hpp>
14 #include <boost/spirit/include/support_argument.hpp>
15 #include <boost/fusion/include/vector.hpp>
16 #include <boost/fusion/include/at.hpp>
17 #include <boost/spirit/include/phoenix_core.hpp>
18 #include <boost/spirit/include/phoenix_operator.hpp>
19 #include <boost/optional.hpp>
20
21 #include <string>
22 #include <iostream>
23 #include "test.hpp"
24
25 using namespace spirit_test;
26
27 int
main()28 main()
29 {
30 using boost::spirit::qi::int_;
31 using boost::spirit::qi::_1;
32 using boost::spirit::qi::_2;
33 using boost::spirit::qi::rule;
34 using boost::spirit::ascii::alpha;
35 using boost::spirit::ascii::char_;
36
37 using boost::fusion::vector;
38 using boost::fusion::at_c;
39 using boost::optional;
40
41 {
42 BOOST_TEST((test("a", char_('a') ^ char_('b') ^ char_('c'))));
43 BOOST_TEST((test("b", char_('a') ^ char_('b') ^ char_('c'))));
44 BOOST_TEST((test("ab", char_('a') ^ char_('b') ^ char_('c'))));
45 BOOST_TEST((test("ba", char_('a') ^ char_('b') ^ char_('c'))));
46 BOOST_TEST((test("abc", char_('a') ^ char_('b') ^ char_('c'))));
47 BOOST_TEST((test("acb", char_('a') ^ char_('b') ^ char_('c'))));
48 BOOST_TEST((test("bca", char_('a') ^ char_('b') ^ char_('c'))));
49 BOOST_TEST((test("bac", char_('a') ^ char_('b') ^ char_('c'))));
50 BOOST_TEST((test("cab", char_('a') ^ char_('b') ^ char_('c'))));
51 BOOST_TEST((test("cba", char_('a') ^ char_('b') ^ char_('c'))));
52
53 BOOST_TEST((!test("cca", char_('a') ^ char_('b') ^ char_('c'))));
54 }
55
56 { // test optional must stay uninitialized
57 optional<int> i;
58 BOOST_TEST((test_attr("", -int_ ^ int_, i)));
59 BOOST_TEST(!i);
60 }
61
62 {
63 vector<optional<int>, optional<char> > attr;
64
65 BOOST_TEST((test_attr("a", int_ ^ alpha, attr)));
66 BOOST_TEST((!at_c<0>(attr)));
67 BOOST_TEST((at_c<1>(attr).get() == 'a'));
68
69 at_c<1>(attr) = optional<char>(); // clear the optional
70 BOOST_TEST((test_attr("123", int_ ^ alpha, attr)));
71 BOOST_TEST((at_c<0>(attr).get() == 123));
72 BOOST_TEST((!at_c<1>(attr)));
73
74 at_c<0>(attr) = optional<int>(); // clear the optional
75 BOOST_TEST((test_attr("123a", int_ ^ alpha, attr)));
76 BOOST_TEST((at_c<0>(attr).get() == 123));
77 BOOST_TEST((at_c<1>(attr).get() == 'a'));
78
79 at_c<0>(attr) = optional<int>(); // clear the optional
80 at_c<1>(attr) = optional<char>(); // clear the optional
81 BOOST_TEST((test_attr("a123", int_ ^ alpha, attr)));
82 BOOST_TEST((at_c<0>(attr).get() == 123));
83 BOOST_TEST((at_c<1>(attr).get() == 'a'));
84 }
85
86 { // test action
87 using namespace boost::phoenix;
88 namespace phx = boost::phoenix;
89
90 optional<int> i;
91 optional<char> c;
92
93 BOOST_TEST((test("123a", (int_ ^ alpha)[(phx::ref(i) = _1, phx::ref(c) = _2)])));
94 BOOST_TEST((i.get() == 123));
95 BOOST_TEST((c.get() == 'a'));
96 }
97
98 { // test rule %=
99
100 typedef vector<optional<int>, optional<char> > attr_type;
101 attr_type attr;
102
103 rule<char const*, attr_type()> r;
104 r %= int_ ^ alpha;
105
106 BOOST_TEST((test_attr("a", r, attr)));
107 BOOST_TEST((!at_c<0>(attr)));
108 BOOST_TEST((at_c<1>(attr).get() == 'a'));
109
110 at_c<1>(attr) = optional<char>(); // clear the optional
111 BOOST_TEST((test_attr("123", r, attr)));
112 BOOST_TEST((at_c<0>(attr).get() == 123));
113 BOOST_TEST((!at_c<1>(attr)));
114
115 at_c<0>(attr) = optional<int>(); // clear the optional
116 BOOST_TEST((test_attr("123a", r, attr)));
117 BOOST_TEST((at_c<0>(attr).get() == 123));
118 BOOST_TEST((at_c<1>(attr).get() == 'a'));
119
120 at_c<0>(attr) = optional<int>(); // clear the optional
121 at_c<1>(attr) = optional<char>(); // clear the optional
122 BOOST_TEST((test_attr("a123", r, attr)));
123 BOOST_TEST((at_c<0>(attr).get() == 123));
124 BOOST_TEST((at_c<1>(attr).get() == 'a'));
125 }
126
127 return boost::report_errors();
128 }
129
130