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 <boost/spirit/include/qi_rule.hpp> |
8 | |
9 | #include <boost/spirit/include/qi_operator.hpp> |
10 | #include <boost/spirit/include/qi_char.hpp> |
11 | #include <boost/spirit/include/qi_string.hpp> |
12 | #include <boost/spirit/include/qi_numeric.hpp> |
13 | #include <boost/spirit/include/qi_auxiliary.hpp> |
14 | #include <boost/spirit/include/qi_directive.hpp> |
15 | #include <boost/spirit/include/qi_nonterminal.hpp> |
16 | #include <boost/spirit/include/qi_action.hpp> |
17 | #include <boost/phoenix/core.hpp> |
18 | #include <boost/phoenix/operator.hpp> |
19 | #include <boost/fusion/include/std_pair.hpp> |
20 | |
21 | #include <string> |
22 | #include <cstring> |
23 | #include <iostream> |
24 | #include "test.hpp" |
25 | |
26 | int |
27 | main() |
28 | { |
29 | using spirit_test::test_attr; |
30 | using spirit_test::test; |
31 | |
32 | using namespace boost::spirit::ascii; |
33 | using namespace boost::spirit::qi::labels; |
34 | using boost::spirit::qi::locals; |
35 | using boost::spirit::qi::rule; |
36 | using boost::spirit::qi::int_; |
37 | using boost::spirit::qi::uint_; |
38 | using boost::spirit::qi::fail; |
39 | using boost::spirit::qi::on_error; |
40 | using boost::spirit::qi::debug; |
41 | using boost::spirit::qi::lit; |
42 | |
43 | namespace phx = boost::phoenix; |
44 | |
45 | { // test unassigned rule |
46 | |
47 | rule<char const*> a; |
48 | BOOST_TEST(!test("x" , a)); |
49 | } |
50 | |
51 | { // alias tests |
52 | |
53 | rule<char const*> a, b, c, d, start; |
54 | |
55 | a = 'a'; |
56 | b = 'b'; |
57 | c = 'c'; |
58 | d = start.alias(); // d will always track start |
59 | |
60 | start = *(a | b | c); |
61 | BOOST_TEST(test("abcabcacb" , d)); |
62 | |
63 | start = (a | b) >> (start | b); |
64 | BOOST_TEST(test("aaaabababaaabbb" , d)); |
65 | } |
66 | |
67 | { // copy tests |
68 | |
69 | rule<char const*> a, b, c, start; |
70 | |
71 | a = 'a'; |
72 | b = 'b'; |
73 | c = 'c'; |
74 | |
75 | // The FF is the dynamic equivalent of start = *(a | b | c); |
76 | start = a; |
77 | start = start.copy() | b; |
78 | start = start.copy() | c; |
79 | start = *(start.copy()); |
80 | |
81 | BOOST_TEST(test("abcabcacb" , start)); |
82 | |
83 | // The FF is the dynamic equivalent of start = (a | b) >> (start | b); |
84 | start = b; |
85 | start = a | start.copy(); |
86 | start = start.copy() >> (start | b); |
87 | |
88 | BOOST_TEST(test("aaaabababaaabbb" , start)); |
89 | BOOST_TEST(test("aaaabababaaabba" , start, false)); |
90 | } |
91 | |
92 | { // context tests |
93 | |
94 | char ch; |
95 | rule<char const*, char()> a; |
96 | a = alpha[_val = _1]; |
97 | |
98 | BOOST_TEST(test("x" , a[phx::ref(ch) = _1])); |
99 | BOOST_TEST(ch == 'x'); |
100 | |
101 | BOOST_TEST(test_attr("z" , a, ch)); // attribute is given. |
102 | BOOST_TEST(ch == 'z'); |
103 | } |
104 | |
105 | { // auto rules tests |
106 | |
107 | char ch = '\0'; |
108 | rule<char const*, char()> a; |
109 | a %= alpha; |
110 | |
111 | BOOST_TEST(test("x" , a[phx::ref(ch) = _1])); |
112 | BOOST_TEST(ch == 'x'); |
113 | ch = '\0'; |
114 | BOOST_TEST(test_attr("z" , a, ch)); // attribute is given. |
115 | BOOST_TEST(ch == 'z'); |
116 | |
117 | a = alpha; // test deduced auto rule behavior |
118 | ch = '\0'; |
119 | BOOST_TEST(test("x" , a[phx::ref(ch) = _1])); |
120 | BOOST_TEST(ch == 'x'); |
121 | ch = '\0'; |
122 | BOOST_TEST(test_attr("z" , a, ch)); // attribute is given. |
123 | BOOST_TEST(ch == 'z'); |
124 | } |
125 | |
126 | { // auto rules tests: allow stl containers as attributes to |
127 | // sequences (in cases where attributes of the elements |
128 | // are convertible to the value_type of the container or if |
129 | // the element itself is an stl container with value_type |
130 | // that is convertible to the value_type of the attribute). |
131 | |
132 | std::string s; |
133 | rule<char const*, std::string()> r; |
134 | r %= char_ >> *(',' >> char_); |
135 | |
136 | BOOST_TEST(test("a,b,c,d,e,f" , r[phx::ref(s) = _1])); |
137 | BOOST_TEST(s == "abcdef" ); |
138 | |
139 | r = char_ >> *(',' >> char_); // test deduced auto rule behavior |
140 | s.clear(); |
141 | BOOST_TEST(test("a,b,c,d,e,f" , r[phx::ref(s) = _1])); |
142 | BOOST_TEST(s == "abcdef" ); |
143 | |
144 | r %= char_ >> char_ >> char_ >> char_ >> char_ >> char_; |
145 | s.clear(); |
146 | BOOST_TEST(test("abcdef" , r[phx::ref(s) = _1])); |
147 | BOOST_TEST(s == "abcdef" ); |
148 | |
149 | r = char_ >> char_ >> char_ >> char_ >> char_ >> char_; |
150 | s.clear(); |
151 | BOOST_TEST(test("abcdef" , r[phx::ref(s) = _1])); |
152 | BOOST_TEST(s == "abcdef" ); |
153 | } |
154 | |
155 | return boost::report_errors(); |
156 | } |
157 | |
158 | |