| 1 | /*============================================================================= | 
|---|
| 2 |     Copyright (c) 2002-2003 Hartmut Kaiser | 
|---|
| 3 |     http://spirit.sourceforge.net/ | 
|---|
| 4 |  | 
|---|
| 5 |     Use, modification and distribution is subject to the Boost Software | 
|---|
| 6 |     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | 
|---|
| 7 |     http://www.boost.org/LICENSE_1_0.txt) | 
|---|
| 8 | =============================================================================*/ | 
|---|
| 9 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 10 | // | 
|---|
| 11 | //  Parser traits tests | 
|---|
| 12 | // | 
|---|
| 13 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 14 |  | 
|---|
| 15 | #include <cassert> | 
|---|
| 16 | #include <iostream> | 
|---|
| 17 | #include <boost/spirit/core.hpp> | 
|---|
| 18 | #include <boost/spirit/actor/assign_actor.hpp> | 
|---|
| 19 |  | 
|---|
| 20 | using namespace std; | 
|---|
| 21 | using namespace boost::spirit; | 
|---|
| 22 |  | 
|---|
| 23 | typedef ref_value_actor<char, assign_action> assign_actor; | 
|---|
| 24 |  | 
|---|
| 25 | //  Test parser_traits templates | 
|---|
| 26 | void | 
|---|
| 27 | parser_traits_tests() | 
|---|
| 28 | { | 
|---|
| 29 | // is_parser_category_tests | 
|---|
| 30 |     typedef chlit<char> plain_t; | 
|---|
| 31 |     typedef optional<chlit<char> > unary_t; | 
|---|
| 32 |     typedef action<chlit<char>, assign_actor> action_t; | 
|---|
| 33 |     typedef sequence<chlit<char>, anychar_parser> binary_t; | 
|---|
| 34 |  | 
|---|
| 35 | // is_parser | 
|---|
| 36 |     BOOST_STATIC_ASSERT(is_parser<plain_t>::value); | 
|---|
| 37 |     BOOST_STATIC_ASSERT(is_parser<unary_t>::value); | 
|---|
| 38 |     BOOST_STATIC_ASSERT(is_parser<action_t>::value); | 
|---|
| 39 |     BOOST_STATIC_ASSERT(is_parser<binary_t>::value); | 
|---|
| 40 |  | 
|---|
| 41 | // is_action_parser | 
|---|
| 42 |     BOOST_STATIC_ASSERT(!is_action_parser<plain_t>::value); | 
|---|
| 43 |     BOOST_STATIC_ASSERT(!is_action_parser<unary_t>::value); | 
|---|
| 44 |     BOOST_STATIC_ASSERT(is_action_parser<action_t>::value); | 
|---|
| 45 |     BOOST_STATIC_ASSERT(!is_action_parser<binary_t>::value); | 
|---|
| 46 |  | 
|---|
| 47 | // is_unary_composite | 
|---|
| 48 |     BOOST_STATIC_ASSERT(!is_unary_composite<plain_t>::value); | 
|---|
| 49 |     BOOST_STATIC_ASSERT(is_unary_composite<unary_t>::value); | 
|---|
| 50 |     BOOST_STATIC_ASSERT(is_unary_composite<action_t>::value);   // action_t _is_ an unary_t! | 
|---|
| 51 |     BOOST_STATIC_ASSERT(!is_unary_composite<binary_t>::value); | 
|---|
| 52 |  | 
|---|
| 53 | // is_binary_composite | 
|---|
| 54 |     BOOST_STATIC_ASSERT(!is_binary_composite<plain_t>::value); | 
|---|
| 55 |     BOOST_STATIC_ASSERT(!is_binary_composite<unary_t>::value); | 
|---|
| 56 |     BOOST_STATIC_ASSERT(!is_binary_composite<action_t>::value); | 
|---|
| 57 |     BOOST_STATIC_ASSERT(is_binary_composite<binary_t>::value); | 
|---|
| 58 |  | 
|---|
| 59 | // is_composite_parser | 
|---|
| 60 |     BOOST_STATIC_ASSERT(!is_composite_parser<plain_t>::value); | 
|---|
| 61 |     BOOST_STATIC_ASSERT(is_composite_parser<unary_t>::value); | 
|---|
| 62 |     BOOST_STATIC_ASSERT(is_composite_parser<action_t>::value);   // action_t _is_ an unary_t! | 
|---|
| 63 |     BOOST_STATIC_ASSERT(is_composite_parser<binary_t>::value); | 
|---|
| 64 |  | 
|---|
| 65 | // is_composite_type_tests | 
|---|
| 66 |     typedef alternative<chlit<char>, anychar_parser> alternative_t; | 
|---|
| 67 |     typedef sequence<chlit<char>, anychar_parser> sequence_t; | 
|---|
| 68 |     typedef sequential_or<chlit<char>, anychar_parser> sequential_or_t; | 
|---|
| 69 |     typedef intersection<chlit<char>, anychar_parser> intersection_t; | 
|---|
| 70 |     typedef difference<chlit<char>, anychar_parser> difference_t; | 
|---|
| 71 |     typedef exclusive_or<chlit<char>, anychar_parser> exclusive_or_t; | 
|---|
| 72 |  | 
|---|
| 73 |     typedef optional<chlit<char> > optional_t; | 
|---|
| 74 |     typedef kleene_star<chlit<char> > kleene_star_t; | 
|---|
| 75 |     typedef positive<chlit<char> > positive_t; | 
|---|
| 76 |  | 
|---|
| 77 | // is_parser | 
|---|
| 78 |     BOOST_STATIC_ASSERT(is_parser<alternative_t>::value); | 
|---|
| 79 |     BOOST_STATIC_ASSERT(is_parser<sequence_t>::value); | 
|---|
| 80 |     BOOST_STATIC_ASSERT(is_parser<sequential_or_t>::value); | 
|---|
| 81 |     BOOST_STATIC_ASSERT(is_parser<intersection_t>::value); | 
|---|
| 82 |     BOOST_STATIC_ASSERT(is_parser<difference_t>::value); | 
|---|
| 83 |     BOOST_STATIC_ASSERT(is_parser<exclusive_or_t>::value); | 
|---|
| 84 |     BOOST_STATIC_ASSERT(is_parser<optional_t>::value); | 
|---|
| 85 |     BOOST_STATIC_ASSERT(is_parser<positive_t>::value); | 
|---|
| 86 |  | 
|---|
| 87 | // is_alternative | 
|---|
| 88 |     BOOST_STATIC_ASSERT(!is_alternative<plain_t>::value); | 
|---|
| 89 |     BOOST_STATIC_ASSERT(!is_alternative<action_t>::value); | 
|---|
| 90 |  | 
|---|
| 91 |     BOOST_STATIC_ASSERT(is_alternative<alternative_t>::value); | 
|---|
| 92 |     BOOST_STATIC_ASSERT(!is_alternative<sequence_t>::value); | 
|---|
| 93 |     BOOST_STATIC_ASSERT(!is_alternative<sequential_or_t>::value); | 
|---|
| 94 |     BOOST_STATIC_ASSERT(!is_alternative<intersection_t>::value); | 
|---|
| 95 |     BOOST_STATIC_ASSERT(!is_alternative<difference_t>::value); | 
|---|
| 96 |     BOOST_STATIC_ASSERT(!is_alternative<exclusive_or_t>::value); | 
|---|
| 97 |  | 
|---|
| 98 |     BOOST_STATIC_ASSERT(!is_alternative<optional_t>::value); | 
|---|
| 99 |     BOOST_STATIC_ASSERT(!is_alternative<kleene_star_t>::value); | 
|---|
| 100 |     BOOST_STATIC_ASSERT(!is_alternative<positive_t>::value); | 
|---|
| 101 |  | 
|---|
| 102 | // is_sequence | 
|---|
| 103 |     BOOST_STATIC_ASSERT(!is_sequence<plain_t>::value); | 
|---|
| 104 |     BOOST_STATIC_ASSERT(!is_sequence<action_t>::value); | 
|---|
| 105 |  | 
|---|
| 106 |     BOOST_STATIC_ASSERT(!is_sequence<alternative_t>::value); | 
|---|
| 107 |     BOOST_STATIC_ASSERT(is_sequence<sequence_t>::value); | 
|---|
| 108 |     BOOST_STATIC_ASSERT(!is_sequence<sequential_or_t>::value); | 
|---|
| 109 |     BOOST_STATIC_ASSERT(!is_sequence<intersection_t>::value); | 
|---|
| 110 |     BOOST_STATIC_ASSERT(!is_sequence<difference_t>::value); | 
|---|
| 111 |     BOOST_STATIC_ASSERT(!is_sequence<exclusive_or_t>::value); | 
|---|
| 112 |  | 
|---|
| 113 |     BOOST_STATIC_ASSERT(!is_sequence<optional_t>::value); | 
|---|
| 114 |     BOOST_STATIC_ASSERT(!is_sequence<kleene_star_t>::value); | 
|---|
| 115 |     BOOST_STATIC_ASSERT(!is_sequence<positive_t>::value); | 
|---|
| 116 |  | 
|---|
| 117 | // is_sequential_or | 
|---|
| 118 |     BOOST_STATIC_ASSERT(!is_sequential_or<plain_t>::value); | 
|---|
| 119 |     BOOST_STATIC_ASSERT(!is_sequential_or<action_t>::value); | 
|---|
| 120 |  | 
|---|
| 121 |     BOOST_STATIC_ASSERT(!is_sequential_or<alternative_t>::value); | 
|---|
| 122 |     BOOST_STATIC_ASSERT(!is_sequential_or<sequence_t>::value); | 
|---|
| 123 |     BOOST_STATIC_ASSERT(is_sequential_or<sequential_or_t>::value); | 
|---|
| 124 |     BOOST_STATIC_ASSERT(!is_sequential_or<intersection_t>::value); | 
|---|
| 125 |     BOOST_STATIC_ASSERT(!is_sequential_or<difference_t>::value); | 
|---|
| 126 |     BOOST_STATIC_ASSERT(!is_sequential_or<exclusive_or_t>::value); | 
|---|
| 127 |  | 
|---|
| 128 |     BOOST_STATIC_ASSERT(!is_sequential_or<optional_t>::value); | 
|---|
| 129 |     BOOST_STATIC_ASSERT(!is_sequential_or<kleene_star_t>::value); | 
|---|
| 130 |     BOOST_STATIC_ASSERT(!is_sequential_or<positive_t>::value); | 
|---|
| 131 |  | 
|---|
| 132 | // is_intersection | 
|---|
| 133 |     BOOST_STATIC_ASSERT(!is_intersection<plain_t>::value); | 
|---|
| 134 |     BOOST_STATIC_ASSERT(!is_intersection<action_t>::value); | 
|---|
| 135 |  | 
|---|
| 136 |     BOOST_STATIC_ASSERT(!is_intersection<alternative_t>::value); | 
|---|
| 137 |     BOOST_STATIC_ASSERT(!is_intersection<sequence_t>::value); | 
|---|
| 138 |     BOOST_STATIC_ASSERT(!is_intersection<sequential_or_t>::value); | 
|---|
| 139 |     BOOST_STATIC_ASSERT(is_intersection<intersection_t>::value); | 
|---|
| 140 |     BOOST_STATIC_ASSERT(!is_intersection<difference_t>::value); | 
|---|
| 141 |     BOOST_STATIC_ASSERT(!is_intersection<exclusive_or_t>::value); | 
|---|
| 142 |  | 
|---|
| 143 |     BOOST_STATIC_ASSERT(!is_intersection<optional_t>::value); | 
|---|
| 144 |     BOOST_STATIC_ASSERT(!is_intersection<kleene_star_t>::value); | 
|---|
| 145 |     BOOST_STATIC_ASSERT(!is_intersection<positive_t>::value); | 
|---|
| 146 |  | 
|---|
| 147 | // is_difference | 
|---|
| 148 |     BOOST_STATIC_ASSERT(!is_difference<plain_t>::value); | 
|---|
| 149 |     BOOST_STATIC_ASSERT(!is_difference<action_t>::value); | 
|---|
| 150 |  | 
|---|
| 151 |     BOOST_STATIC_ASSERT(!is_difference<alternative_t>::value); | 
|---|
| 152 |     BOOST_STATIC_ASSERT(!is_difference<sequence_t>::value); | 
|---|
| 153 |     BOOST_STATIC_ASSERT(!is_difference<sequential_or_t>::value); | 
|---|
| 154 |     BOOST_STATIC_ASSERT(!is_difference<intersection_t>::value); | 
|---|
| 155 |     BOOST_STATIC_ASSERT(is_difference<difference_t>::value); | 
|---|
| 156 |     BOOST_STATIC_ASSERT(!is_difference<exclusive_or_t>::value); | 
|---|
| 157 |  | 
|---|
| 158 |     BOOST_STATIC_ASSERT(!is_difference<optional_t>::value); | 
|---|
| 159 |     BOOST_STATIC_ASSERT(!is_difference<kleene_star_t>::value); | 
|---|
| 160 |     BOOST_STATIC_ASSERT(!is_difference<positive_t>::value); | 
|---|
| 161 |  | 
|---|
| 162 | // is_exclusive_or | 
|---|
| 163 |     BOOST_STATIC_ASSERT(!is_exclusive_or<plain_t>::value); | 
|---|
| 164 |     BOOST_STATIC_ASSERT(!is_exclusive_or<action_t>::value); | 
|---|
| 165 |  | 
|---|
| 166 |     BOOST_STATIC_ASSERT(!is_exclusive_or<alternative_t>::value); | 
|---|
| 167 |     BOOST_STATIC_ASSERT(!is_exclusive_or<sequence_t>::value); | 
|---|
| 168 |     BOOST_STATIC_ASSERT(!is_exclusive_or<sequential_or_t>::value); | 
|---|
| 169 |     BOOST_STATIC_ASSERT(!is_exclusive_or<intersection_t>::value); | 
|---|
| 170 |     BOOST_STATIC_ASSERT(!is_exclusive_or<difference_t>::value); | 
|---|
| 171 |     BOOST_STATIC_ASSERT(is_exclusive_or<exclusive_or_t>::value); | 
|---|
| 172 |  | 
|---|
| 173 |     BOOST_STATIC_ASSERT(!is_exclusive_or<optional_t>::value); | 
|---|
| 174 |     BOOST_STATIC_ASSERT(!is_exclusive_or<kleene_star_t>::value); | 
|---|
| 175 |     BOOST_STATIC_ASSERT(!is_exclusive_or<positive_t>::value); | 
|---|
| 176 |  | 
|---|
| 177 | // is_optional | 
|---|
| 178 |     BOOST_STATIC_ASSERT(!is_optional<plain_t>::value); | 
|---|
| 179 |     BOOST_STATIC_ASSERT(!is_optional<action_t>::value); | 
|---|
| 180 |  | 
|---|
| 181 |     BOOST_STATIC_ASSERT(!is_optional<alternative_t>::value); | 
|---|
| 182 |     BOOST_STATIC_ASSERT(!is_optional<sequence_t>::value); | 
|---|
| 183 |     BOOST_STATIC_ASSERT(!is_optional<sequential_or_t>::value); | 
|---|
| 184 |     BOOST_STATIC_ASSERT(!is_optional<intersection_t>::value); | 
|---|
| 185 |     BOOST_STATIC_ASSERT(!is_optional<difference_t>::value); | 
|---|
| 186 |     BOOST_STATIC_ASSERT(!is_optional<exclusive_or_t>::value); | 
|---|
| 187 |  | 
|---|
| 188 |     BOOST_STATIC_ASSERT(is_optional<optional_t>::value); | 
|---|
| 189 |     BOOST_STATIC_ASSERT(!is_optional<kleene_star_t>::value); | 
|---|
| 190 |     BOOST_STATIC_ASSERT(!is_optional<positive_t>::value); | 
|---|
| 191 |  | 
|---|
| 192 | // is_kleene_star | 
|---|
| 193 |     BOOST_STATIC_ASSERT(!is_kleene_star<plain_t>::value); | 
|---|
| 194 |     BOOST_STATIC_ASSERT(!is_kleene_star<action_t>::value); | 
|---|
| 195 |  | 
|---|
| 196 |     BOOST_STATIC_ASSERT(!is_kleene_star<alternative_t>::value); | 
|---|
| 197 |     BOOST_STATIC_ASSERT(!is_kleene_star<sequence_t>::value); | 
|---|
| 198 |     BOOST_STATIC_ASSERT(!is_kleene_star<sequential_or_t>::value); | 
|---|
| 199 |     BOOST_STATIC_ASSERT(!is_kleene_star<intersection_t>::value); | 
|---|
| 200 |     BOOST_STATIC_ASSERT(!is_kleene_star<difference_t>::value); | 
|---|
| 201 |     BOOST_STATIC_ASSERT(!is_kleene_star<exclusive_or_t>::value); | 
|---|
| 202 |  | 
|---|
| 203 |     BOOST_STATIC_ASSERT(!is_kleene_star<optional_t>::value); | 
|---|
| 204 |     BOOST_STATIC_ASSERT(is_kleene_star<kleene_star_t>::value); | 
|---|
| 205 |     BOOST_STATIC_ASSERT(!is_kleene_star<positive_t>::value); | 
|---|
| 206 |  | 
|---|
| 207 | // is_positive | 
|---|
| 208 |     BOOST_STATIC_ASSERT(!is_positive<plain_t>::value); | 
|---|
| 209 |     BOOST_STATIC_ASSERT(!is_positive<action_t>::value); | 
|---|
| 210 |  | 
|---|
| 211 |     BOOST_STATIC_ASSERT(!is_positive<alternative_t>::value); | 
|---|
| 212 |     BOOST_STATIC_ASSERT(!is_positive<sequence_t>::value); | 
|---|
| 213 |     BOOST_STATIC_ASSERT(!is_positive<sequential_or_t>::value); | 
|---|
| 214 |     BOOST_STATIC_ASSERT(!is_positive<intersection_t>::value); | 
|---|
| 215 |     BOOST_STATIC_ASSERT(!is_positive<difference_t>::value); | 
|---|
| 216 |     BOOST_STATIC_ASSERT(!is_positive<exclusive_or_t>::value); | 
|---|
| 217 |  | 
|---|
| 218 |     BOOST_STATIC_ASSERT(!is_positive<optional_t>::value); | 
|---|
| 219 |     BOOST_STATIC_ASSERT(!is_positive<kleene_star_t>::value); | 
|---|
| 220 |     BOOST_STATIC_ASSERT(is_positive<positive_t>::value); | 
|---|
| 221 | } | 
|---|
| 222 |  | 
|---|
| 223 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 224 | //  Test parser extraction templates | 
|---|
| 225 | void | 
|---|
| 226 | parser_extraction_tests() | 
|---|
| 227 | { | 
|---|
| 228 |     typedef chlit<char> plain_t; | 
|---|
| 229 |     typedef optional<chlit<char> > unary_t; | 
|---|
| 230 |     typedef action<chlit<char>, assign_actor> action_t; | 
|---|
| 231 |     typedef sequence<chlit<char>, anychar_parser> binary_t; | 
|---|
| 232 |  | 
|---|
| 233 | // parser type extraction templates | 
|---|
| 234 |     BOOST_STATIC_ASSERT(( | 
|---|
| 235 |         ::boost::is_same< | 
|---|
| 236 |                 chlit<char>, unary_subject<unary_t>::type | 
|---|
| 237 |             >::value)); | 
|---|
| 238 |     BOOST_STATIC_ASSERT(( | 
|---|
| 239 |         ::boost::is_same< | 
|---|
| 240 |                 chlit<char>, action_subject<action_t>::type | 
|---|
| 241 |             >::value)); | 
|---|
| 242 |     BOOST_STATIC_ASSERT(( | 
|---|
| 243 |         ::boost::is_same< | 
|---|
| 244 |                 assign_actor, semantic_action<action_t>::type | 
|---|
| 245 |             >::value)); | 
|---|
| 246 |     BOOST_STATIC_ASSERT(( | 
|---|
| 247 |         ::boost::is_same< | 
|---|
| 248 |                 chlit<char>, binary_left_subject<binary_t>::type | 
|---|
| 249 |             >::value)); | 
|---|
| 250 |     BOOST_STATIC_ASSERT(( | 
|---|
| 251 |         ::boost::is_same< | 
|---|
| 252 |                 anychar_parser, binary_right_subject<binary_t>::type | 
|---|
| 253 |             >::value)); | 
|---|
| 254 |  | 
|---|
| 255 | // parser object extraction functions | 
|---|
| 256 |     assert(1 == parse("aaaa", get_unary_subject(*ch_p('a'))).length); | 
|---|
| 257 |  | 
|---|
| 258 | char c = 'b'; | 
|---|
| 259 |  | 
|---|
| 260 |     assert(1 == parse("aaaa", get_action_subject(ch_p('a')[assign(c)])).length); | 
|---|
| 261 |     assert(c == 'b'); | 
|---|
| 262 |  | 
|---|
| 263 |     assert(1 == parse("aaaa", | 
|---|
| 264 |         ch_p('a')[ get_semantic_action(ch_p('b')[assign(c)]) ]).length); | 
|---|
| 265 |     assert(c == 'a'); | 
|---|
| 266 |  | 
|---|
| 267 |     assert(1 == parse("abab", | 
|---|
| 268 |         get_binary_left_subject(ch_p('a') >> ch_p('b'))).length); | 
|---|
| 269 |     assert(1 == parse("baba", | 
|---|
| 270 |         get_binary_right_subject(ch_p('a') >> ch_p('b'))).length); | 
|---|
| 271 | } | 
|---|
| 272 |  | 
|---|
| 273 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 274 | // | 
|---|
| 275 | //  Main | 
|---|
| 276 | // | 
|---|
| 277 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 278 | int | 
|---|
| 279 | main() | 
|---|
| 280 | { | 
|---|
| 281 |     parser_traits_tests(); | 
|---|
| 282 |     parser_extraction_tests(); | 
|---|
| 283 |  | 
|---|
| 284 |     cout << "Tests concluded successfully\n"; | 
|---|
| 285 |     return 0; | 
|---|
| 286 | } | 
|---|
| 287 |  | 
|---|