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