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 | #include <boost/spirit/include/qi_grammar.hpp> |
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_nonterminal.hpp> |
14 | #include <boost/spirit/include/qi_action.hpp> |
15 | #include <boost/phoenix/core.hpp> |
16 | #include <boost/phoenix/operator.hpp> |
17 | |
18 | #include <string> |
19 | #include <iostream> |
20 | #include "test.hpp" |
21 | |
22 | using spirit_test::test; |
23 | using spirit_test::test_attr; |
24 | |
25 | using boost::spirit::ascii::space_type; |
26 | using boost::spirit::ascii::space; |
27 | using boost::spirit::int_; |
28 | using boost::spirit::qi::grammar; |
29 | using boost::spirit::qi::rule; |
30 | using boost::spirit::_val; |
31 | using boost::spirit::_r1; |
32 | using boost::spirit::lit; |
33 | |
34 | struct num_list : grammar<char const*, space_type> |
35 | { |
36 | num_list() : base_type(start) |
37 | { |
38 | using boost::spirit::int_; |
39 | num = int_; |
40 | start = num >> *(',' >> num); |
41 | } |
42 | |
43 | rule<char const*, space_type> start, num; |
44 | }; |
45 | |
46 | struct inh_g : grammar<char const*, int(int), space_type> |
47 | { |
48 | inh_g() : base_type(start) |
49 | { |
50 | start = lit("inherited" )[_val = _r1]; |
51 | } |
52 | |
53 | rule<char const*, int(int), space_type> start, num; |
54 | }; |
55 | |
56 | struct my_skipper : grammar<char const*> |
57 | { |
58 | my_skipper() : base_type(start) |
59 | { |
60 | start = space; |
61 | } |
62 | |
63 | rule<char const*> start, num; |
64 | }; |
65 | |
66 | struct num_list2 : grammar<char const*, my_skipper> |
67 | { |
68 | num_list2() : base_type(start) |
69 | { |
70 | using boost::spirit::int_; |
71 | num = int_; |
72 | start = num >> *(',' >> num); |
73 | } |
74 | |
75 | rule<char const*, my_skipper> start, num; |
76 | }; |
77 | |
78 | template <typename Iterator, typename Skipper> |
79 | struct num_list3 : grammar<Iterator, Skipper> |
80 | { |
81 | template <typename Class> |
82 | num_list3(Class&) : grammar<Iterator, Skipper>(start) |
83 | { |
84 | using boost::spirit::int_; |
85 | num = int_; |
86 | start = num >> *(',' >> num); |
87 | } |
88 | |
89 | rule<Iterator, Skipper> start, num; |
90 | }; |
91 | |
92 | int |
93 | main() |
94 | { |
95 | { // simple grammar test |
96 | |
97 | num_list nlist; |
98 | BOOST_TEST(test("123, 456, 789" , nlist, space)); |
99 | } |
100 | |
101 | { // simple grammar test with user-skipper |
102 | |
103 | num_list2 nlist; |
104 | my_skipper skip; |
105 | BOOST_TEST(test("123, 456, 789" , nlist, skip)); |
106 | } |
107 | |
108 | { // direct access to the rules |
109 | |
110 | num_list g; |
111 | BOOST_TEST(test("123" , g.num, space)); |
112 | BOOST_TEST(test("123, 456, 789" , g.start, space)); |
113 | } |
114 | |
115 | { // grammar with inherited attributes |
116 | |
117 | inh_g g; |
118 | int n = -1; |
119 | BOOST_TEST(test_attr("inherited" , g.start(123), n, space)); // direct to the rule |
120 | BOOST_TEST(n == 123); |
121 | BOOST_TEST(test_attr("inherited" , g(123), n, space)); // using the grammar |
122 | BOOST_TEST(n == 123); |
123 | } |
124 | |
125 | return boost::report_errors(); |
126 | } |
127 | |
128 | |