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