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