1 /*=============================================================================
2     Copyright (c) 2001-2010 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 #define BOOST_SPIRIT_DEBUG
8 
9 #include <boost/detail/lightweight_test.hpp>
10 #include <boost/spirit/include/qi_operator.hpp>
11 #include <boost/spirit/include/qi_char.hpp>
12 #include <boost/spirit/include/qi_string.hpp>
13 #include <boost/spirit/include/qi_numeric.hpp>
14 #include <boost/spirit/include/qi_auxiliary.hpp>
15 #include <boost/spirit/include/qi_nonterminal.hpp>
16 #include <boost/spirit/include/qi_action.hpp>
17 #include <boost/spirit/include/phoenix_core.hpp>
18 #include <boost/spirit/include/phoenix_operator.hpp>
19 #include <boost/spirit/include/phoenix_object.hpp>
20 #include <boost/spirit/include/phoenix_bind.hpp>
21 #include <boost/fusion/include/std_pair.hpp>
22 
23 #include <string>
24 #include <cstring>
25 #include <iostream>
26 #include "test.hpp"
27 
28 int
main()29 main()
30 {
31     using spirit_test::test_attr;
32     using spirit_test::test;
33 
34     using namespace boost::spirit::ascii;
35     using namespace boost::spirit::qi::labels;
36     using boost::spirit::qi::locals;
37     using boost::spirit::qi::rule;
38     using boost::spirit::qi::int_;
39     using boost::spirit::qi::fail;
40     using boost::spirit::qi::on_error;
41     using boost::spirit::qi::debug;
42     using boost::spirit::qi::alpha;
43 
44     namespace phx = boost::phoenix;
45 
46     { // basic tests
47 
48         rule<char const*> a, b, c, start;
49 
50         a = 'a';
51         b = 'b';
52         c = 'c';
53         BOOST_SPIRIT_DEBUG_NODE(a);
54         BOOST_SPIRIT_DEBUG_NODE(b);
55         BOOST_SPIRIT_DEBUG_NODE(c);
56 
57         start = *(a | b | c);
58         BOOST_SPIRIT_DEBUG_NODE(start);
59         BOOST_TEST(test("abcabcacb", start));
60 
61         start = (a | b) >> (start | b);
62         BOOST_SPIRIT_DEBUG_NODE(start);
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 w/ skipper
71 
72         rule<char const*, space_type> a, b, c, start;
73 
74         a = 'a';
75         b = 'b';
76         c = 'c';
77         BOOST_SPIRIT_DEBUG_NODE(a);
78         BOOST_SPIRIT_DEBUG_NODE(b);
79         BOOST_SPIRIT_DEBUG_NODE(c);
80 
81         start = *(a | b | c);
82         BOOST_SPIRIT_DEBUG_NODE(start);
83         BOOST_TEST(test(" a b c a b c a c b ", start, space));
84 
85         start = (a | b) >> (start | b);
86         BOOST_SPIRIT_DEBUG_NODE(start);
87         BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start, space));
88         BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start, space, false));
89     }
90 
91     { // std::container attributes
92 
93         typedef boost::fusion::vector<int, char> fs;
94         rule<char const*, std::vector<fs>(), space_type> start;
95         start = *(int_ >> alpha);
96 
97         BOOST_SPIRIT_DEBUG_NODE(start);
98         BOOST_TEST(test("1 a 2 b 3 c", start, space));
99     }
100 
101     { // error handling
102 
103         using namespace boost::spirit::ascii;
104         using boost::phoenix::construct;
105         using boost::phoenix::bind;
106 
107         rule<char const*> r;
108         r = '(' > int_ > ',' > int_ > ')';
109 
110         on_error<fail>
111         (
112             r, std::cout
113                 << phx::val("Error! Expecting: ")
114                 << _4
115                 << phx::val(", got: \"")
116                 << construct<std::string>(_3, _2)
117                 << phx::val("\"")
118                 << std::endl
119         );
120 
121         BOOST_SPIRIT_DEBUG_NODE(r);
122         BOOST_TEST(test("(123,456)", r));
123         BOOST_TEST(!test("(abc,def)", r));
124         BOOST_TEST(!test("(123,456]", r));
125         BOOST_TEST(!test("(123;456)", r));
126         BOOST_TEST(!test("[123,456]", r));
127     }
128 
129     return boost::report_errors();
130 }
131 
132