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 | |
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_auxiliary.hpp> |
13 | #include <boost/spirit/include/qi_directive.hpp> |
14 | #include <boost/spirit/include/qi_nonterminal.hpp> |
15 | #include <boost/spirit/include/qi_action.hpp> |
16 | #include <boost/phoenix/core.hpp> |
17 | #include <boost/phoenix/operator.hpp> |
18 | #include <boost/phoenix/object.hpp> |
19 | #include <boost/phoenix/bind.hpp> |
20 | #include <boost/fusion/include/std_pair.hpp> |
21 | |
22 | #include <string> |
23 | #include <cstring> |
24 | #include <iostream> |
25 | #include "test.hpp" |
26 | |
27 | int |
28 | main() |
29 | { |
30 | using spirit_test::test_attr; |
31 | using spirit_test::test; |
32 | |
33 | using namespace boost::spirit::ascii; |
34 | using namespace boost::spirit::qi::labels; |
35 | using boost::spirit::qi::locals; |
36 | using boost::spirit::qi::rule; |
37 | using boost::spirit::qi::int_; |
38 | using boost::spirit::qi::uint_; |
39 | using boost::spirit::qi::fail; |
40 | using boost::spirit::qi::on_error; |
41 | using boost::spirit::qi::debug; |
42 | using boost::spirit::qi::lit; |
43 | |
44 | namespace phx = boost::phoenix; |
45 | |
46 | |
47 | { // show that ra = rb and ra %= rb works as expected |
48 | rule<char const*, int() > ra, rb; |
49 | int attr; |
50 | |
51 | ra %= int_; |
52 | BOOST_TEST(test_attr("123" , ra, attr)); |
53 | BOOST_TEST(attr == 123); |
54 | |
55 | rb %= ra; |
56 | BOOST_TEST(test_attr("123" , rb, attr)); |
57 | BOOST_TEST(attr == 123); |
58 | |
59 | rb = ra; |
60 | BOOST_TEST(test_attr("123" , rb, attr)); |
61 | BOOST_TEST(attr == 123); |
62 | } |
63 | |
64 | { // std::string as container attribute with auto rules |
65 | |
66 | rule<char const*, std::string()> text; |
67 | text %= +(!char_(')') >> !char_('>') >> char_); |
68 | std::string attr; |
69 | BOOST_TEST(test_attr("x" , text, attr)); |
70 | BOOST_TEST(attr == "x" ); |
71 | |
72 | // test deduced auto rule behavior |
73 | text = +(!char_(')') >> !char_('>') >> char_); |
74 | attr.clear(); |
75 | BOOST_TEST(test_attr("x" , text, attr)); |
76 | BOOST_TEST(attr == "x" ); |
77 | } |
78 | |
79 | { // error handling |
80 | |
81 | using namespace boost::spirit::ascii; |
82 | using boost::phoenix::construct; |
83 | using boost::phoenix::bind; |
84 | |
85 | rule<char const*> r; |
86 | r = '(' > int_ > ',' > int_ > ')'; |
87 | |
88 | on_error<fail> |
89 | ( |
90 | r, f: std::cout |
91 | << phx::val(t: "Error! Expecting: " ) |
92 | << _4 |
93 | << phx::val(t: ", got: \"" ) |
94 | << construct<std::string>(a0: _3, a1: _2) |
95 | << phx::val(t: "\"" ) |
96 | << std::endl |
97 | ); |
98 | |
99 | BOOST_TEST(test("(123,456)" , r)); |
100 | BOOST_TEST(!test("(abc,def)" , r)); |
101 | BOOST_TEST(!test("(123,456]" , r)); |
102 | BOOST_TEST(!test("(123;456)" , r)); |
103 | BOOST_TEST(!test("[123,456]" , r)); |
104 | } |
105 | |
106 | { // specifying the encoding |
107 | |
108 | typedef boost::spirit::char_encoding::iso8859_1 iso8859_1; |
109 | rule<char const*, iso8859_1> r; |
110 | |
111 | r = no_case['\xE1']; |
112 | BOOST_TEST(test("\xC1" , r)); |
113 | r = no_case[char_('\xE1')]; |
114 | BOOST_TEST(test("\xC1" , r)); |
115 | |
116 | r = no_case[char_("\xE5-\xEF" )]; |
117 | BOOST_TEST(test("\xC9" , r)); |
118 | BOOST_TEST(!test("\xFF" , r)); |
119 | |
120 | r = no_case["\xE1\xC1" ]; |
121 | BOOST_TEST(test("\xC1\xE1" , r)); |
122 | r = no_case[lit("\xE1\xC1" )]; |
123 | BOOST_TEST(test("\xC1\xE1" , r)); |
124 | } |
125 | |
126 | { |
127 | typedef boost::variant<double, int> v_type; |
128 | rule<const char*, v_type()> r1 = int_; |
129 | v_type v; |
130 | BOOST_TEST(test_attr("1" , r1, v) && v.which() == 1 && |
131 | boost::get<int>(v) == 1); |
132 | |
133 | typedef boost::optional<int> ov_type; |
134 | rule<const char*, ov_type()> r2 = int_; |
135 | ov_type ov; |
136 | BOOST_TEST(test_attr("1" , r2, ov) && ov && boost::get<int>(ov) == 1); |
137 | } |
138 | |
139 | // test handling of single element fusion sequences |
140 | { |
141 | using boost::fusion::vector; |
142 | using boost::fusion::at_c; |
143 | rule<const char*, vector<int>()> r = int_; |
144 | |
145 | vector<int> v(0); |
146 | BOOST_TEST(test_attr("1" , r, v) && at_c<0>(v) == 1); |
147 | } |
148 | |
149 | { |
150 | using boost::fusion::vector; |
151 | using boost::fusion::at_c; |
152 | rule<const char*, vector<unsigned int>()> r = uint_; |
153 | |
154 | vector<unsigned int> v(0); |
155 | BOOST_TEST(test_attr("1" , r, v) && at_c<0>(v) == 1); |
156 | } |
157 | |
158 | /////////////////////////////////////////////////////////////////////////// |
159 | { |
160 | using boost::spirit::qi::int_; |
161 | using boost::spirit::qi::_1; |
162 | using boost::spirit::qi::_val; |
163 | using boost::spirit::qi::space; |
164 | using boost::spirit::qi::space_type; |
165 | |
166 | rule<const char*, int()> r1 = int_; |
167 | rule<const char*, int(), space_type> r2 = int_; |
168 | |
169 | int i = 0; |
170 | int j = 0; |
171 | BOOST_TEST(test_attr("456" , r1[_val = _1], i) && i == 456); |
172 | BOOST_TEST(test_attr(" 456" , r2[_val = _1], j, space) && j == 456); |
173 | } |
174 | |
175 | #if 0 // disabling test (can't fix) |
176 | { |
177 | using boost::spirit::qi::lexeme; |
178 | using boost::spirit::qi::alnum; |
179 | |
180 | rule<const char*, std::string()> literal_; |
181 | literal_ = lexeme[ +(alnum | '_') ]; |
182 | |
183 | std::string attr; |
184 | BOOST_TEST(test_attr("foo_bar" , literal_, attr) && attr == "foo_bar" ); |
185 | std::cout << attr << std::endl; |
186 | } |
187 | #endif |
188 | |
189 | return boost::report_errors(); |
190 | } |
191 | |
192 | |