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