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_int.hpp> |
13 | #include <boost/spirit/include/qi_uint.hpp> |
14 | #include <boost/spirit/include/qi_nonterminal.hpp> |
15 | #include <boost/spirit/include/qi_action.hpp> |
16 | #include <boost/fusion/include/std_pair.hpp> |
17 | |
18 | #include <string> |
19 | #include <cstring> |
20 | #include <iostream> |
21 | #include "test.hpp" |
22 | |
23 | int |
24 | main() |
25 | { |
26 | using spirit_test::test_attr; |
27 | using spirit_test::test; |
28 | |
29 | using namespace boost::spirit::ascii; |
30 | using namespace boost::spirit::qi::labels; |
31 | using boost::spirit::qi::locals; |
32 | using boost::spirit::qi::rule; |
33 | using boost::spirit::qi::int_; |
34 | using boost::spirit::qi::uint_; |
35 | using boost::spirit::qi::fail; |
36 | using boost::spirit::qi::on_error; |
37 | using boost::spirit::qi::debug; |
38 | using boost::spirit::qi::lit; |
39 | |
40 | { // basic tests |
41 | |
42 | rule<char const*> a, b, c, start; |
43 | |
44 | a = 'a'; |
45 | b = 'b'; |
46 | c = 'c'; |
47 | |
48 | a.name(str: "a" ); |
49 | b.name(str: "b" ); |
50 | c.name(str: "c" ); |
51 | start.name(str: "start" ); |
52 | |
53 | debug(r&: a); |
54 | debug(r&: b); |
55 | debug(r&: c); |
56 | debug(r&: start); |
57 | |
58 | start = *(a | b | c); |
59 | BOOST_TEST(test("abcabcacb" , start)); |
60 | |
61 | start = (a | b) >> (start | b); |
62 | BOOST_TEST(test("aaaabababaaabbb" , start)); |
63 | BOOST_TEST(test("aaaabababaaabba" , start, false)); |
64 | |
65 | // ignore the skipper! |
66 | BOOST_TEST(test("aaaabababaaabba" , start, space, false)); |
67 | } |
68 | |
69 | { // basic tests with direct initialization |
70 | |
71 | rule<char const*> a ('a'); |
72 | rule<char const*> b ('b'); |
73 | rule<char const*> c ('c'); |
74 | #ifdef BOOST_CLANG |
75 | # pragma clang diagnostic push |
76 | // variable 'start' is uninitialized when used within its own initialization |
77 | # pragma clang diagnostic ignored "-Wuninitialized" |
78 | #endif |
79 | rule<char const*> start = (a | b) >> (start | b); |
80 | #ifdef BOOST_CLANG |
81 | # pragma clang diagnostic pop |
82 | #endif |
83 | |
84 | BOOST_TEST(test("aaaabababaaabbb" , start)); |
85 | BOOST_TEST(test("aaaabababaaabba" , start, false)); |
86 | |
87 | // ignore the skipper! |
88 | BOOST_TEST(test("aaaabababaaabba" , start, space, false)); |
89 | } |
90 | |
91 | { // basic tests w/ skipper |
92 | rule<char const*, space_type> a, b, c, start; |
93 | |
94 | a = 'a'; |
95 | b = 'b'; |
96 | c = 'c'; |
97 | |
98 | a.name(str: "a" ); |
99 | b.name(str: "b" ); |
100 | c.name(str: "c" ); |
101 | start.name(str: "start" ); |
102 | |
103 | debug(r&: a); |
104 | debug(r&: b); |
105 | debug(r&: c); |
106 | debug(r&: start); |
107 | |
108 | start = *(a | b | c); |
109 | BOOST_TEST(test(" a b c a b c a c b " , start, space)); |
110 | |
111 | start = (a | b) >> (start | b); |
112 | BOOST_TEST(test(" a a a a b a b a b a a a b b b " , start, space)); |
113 | BOOST_TEST(test(" a a a a b a b a b a a a b b a " , start, space, false)); |
114 | } |
115 | |
116 | { // basic tests w/ skipper but no final post-skip |
117 | |
118 | rule<char const*, space_type> a, b, c, start; |
119 | |
120 | a = 'a'; |
121 | b = 'b'; |
122 | c = 'c'; |
123 | |
124 | a.name(str: "a" ); |
125 | b.name(str: "b" ); |
126 | c.name(str: "c" ); |
127 | start.name(str: "start" ); |
128 | |
129 | debug(r&: a); |
130 | debug(r&: b); |
131 | debug(r&: c); |
132 | debug(r&: start); |
133 | |
134 | start = *(a | b) >> c; |
135 | |
136 | using boost::spirit::qi::phrase_parse; |
137 | using boost::spirit::qi::skip_flag; |
138 | { |
139 | char const *s1 = " a b a a b b a c ... " |
140 | , *const e1 = s1 + std::strlen(s: s1); |
141 | BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::dont_postskip) |
142 | && s1 == e1 - 5); |
143 | } |
144 | |
145 | start = (a | b) >> (start | c); |
146 | { |
147 | char const *s1 = " a a a a b a b a b a a a b b b c " |
148 | , *const e1 = s1 + std::strlen(s: s1); |
149 | BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::postskip) |
150 | && s1 == e1); |
151 | } |
152 | { |
153 | char const *s1 = " a a a a b a b a b a a a b b b c " |
154 | , *const e1 = s1 + std::strlen(s: s1); |
155 | BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::dont_postskip) |
156 | && s1 == e1 - 1); |
157 | } |
158 | } |
159 | |
160 | return boost::report_errors(); |
161 | } |
162 | |
163 | |