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#ifndef BOOST_SPIRIT_REFACTORING_IPP 10#define BOOST_SPIRIT_REFACTORING_IPP 11 12/////////////////////////////////////////////////////////////////////////////// 13namespace boost { namespace spirit { 14 15BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 16 17/////////////////////////////////////////////////////////////////////////////// 18// 19// The struct 'self_nested_refactoring' is used to indicate, that the 20// refactoring algorithm should be 'self-nested'. 21// 22// The struct 'non_nested_refactoring' is used to indicate, that no nesting 23// of refactoring algorithms is reqired. 24// 25/////////////////////////////////////////////////////////////////////////////// 26 27struct non_nested_refactoring { typedef non_nested_refactoring embed_t; }; 28struct self_nested_refactoring { typedef self_nested_refactoring embed_t; }; 29 30/////////////////////////////////////////////////////////////////////////////// 31namespace impl { 32 33/////////////////////////////////////////////////////////////////////////////// 34// 35// Helper templates for refactoring parsers 36// 37/////////////////////////////////////////////////////////////////////////////// 38 39 /////////////////////////////////////////////////////////////////////////// 40 // 41 // refactor the left unary operand of a binary parser 42 // 43 // The refactoring should be done only if the left operand is an 44 // unary_parser_category parser. 45 // 46 /////////////////////////////////////////////////////////////////////////// 47 48 /////////////////////////////////////////////////////////////////////////// 49 template <typename CategoryT> 50 struct refactor_unary_nested { 51 52 template < 53 typename ParserT, typename NestedT, 54 typename ScannerT, typename BinaryT 55 > 56 static typename parser_result<ParserT, ScannerT>::type 57 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, 58 NestedT const& /*nested_d*/) 59 { 60 return binary.parse(scan); 61 } 62 }; 63 64 template <> 65 struct refactor_unary_nested<unary_parser_category> { 66 67 template < 68 typename ParserT, typename ScannerT, typename BinaryT, 69 typename NestedT 70 > 71 static typename parser_result<ParserT, ScannerT>::type 72 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, 73 NestedT const& nested_d) 74 { 75 typedef typename BinaryT::parser_generator_t op_t; 76 typedef 77 typename BinaryT::left_t::parser_generator_t 78 unary_t; 79 80 return 81 unary_t::generate( 82 nested_d[ 83 op_t::generate(binary.left().subject(), binary.right()) 84 ] 85 ).parse(scan); 86 } 87 }; 88 89 /////////////////////////////////////////////////////////////////////////// 90 template <typename CategoryT> 91 struct refactor_unary_non_nested { 92 93 template <typename ParserT, typename ScannerT, typename BinaryT> 94 static typename parser_result<ParserT, ScannerT>::type 95 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) 96 { 97 return binary.parse(scan); 98 } 99 }; 100 101 template <> 102 struct refactor_unary_non_nested<unary_parser_category> { 103 104 template <typename ParserT, typename ScannerT, typename BinaryT> 105 static typename parser_result<ParserT, ScannerT>::type 106 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) 107 { 108 typedef typename BinaryT::parser_generator_t op_t; 109 typedef 110 typename BinaryT::left_t::parser_generator_t 111 unary_t; 112 113 return unary_t::generate( 114 op_t::generate(binary.left().subject(), binary.right()) 115 ).parse(scan); 116 } 117 }; 118 119 /////////////////////////////////////////////////////////////////////////// 120 template <typename NestedT> 121 struct refactor_unary_type { 122 123 template <typename ParserT, typename ScannerT, typename BinaryT> 124 static typename parser_result<ParserT, ScannerT>::type 125 parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, 126 NestedT const& nested_d) 127 { 128 typedef 129 typename BinaryT::left_t::parser_category_t 130 parser_category_t; 131 132 return refactor_unary_nested<parser_category_t>:: 133 parse(p, scan, binary, nested_d); 134 } 135 }; 136 137 template <> 138 struct refactor_unary_type<non_nested_refactoring> { 139 140 template <typename ParserT, typename ScannerT, typename BinaryT> 141 static typename parser_result<ParserT, ScannerT>::type 142 parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, 143 non_nested_refactoring const&) 144 { 145 typedef 146 typename BinaryT::left_t::parser_category_t 147 parser_category_t; 148 149 return refactor_unary_non_nested<parser_category_t>:: 150 parse(p, scan, binary); 151 } 152 153 }; 154 155 template <> 156 struct refactor_unary_type<self_nested_refactoring> { 157 158 template <typename ParserT, typename ScannerT, typename BinaryT> 159 static typename parser_result<ParserT, ScannerT>::type 160 parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, 161 self_nested_refactoring const &nested_tag) 162 { 163 typedef 164 typename BinaryT::left_t::parser_category_t 165 parser_category_t; 166 typedef typename ParserT::parser_generator_t parser_generator_t; 167 168 parser_generator_t nested_d(nested_tag); 169 return refactor_unary_nested<parser_category_t>:: 170 parse(p, scan, binary, nested_d); 171 } 172 173 }; 174 175 /////////////////////////////////////////////////////////////////////////// 176 // 177 // refactor the action on the left operand of a binary parser 178 // 179 // The refactoring should be done only if the left operand is an 180 // action_parser_category parser. 181 // 182 /////////////////////////////////////////////////////////////////////////// 183 184 /////////////////////////////////////////////////////////////////////////// 185 template <typename CategoryT> 186 struct refactor_action_nested { 187 188 template < 189 typename ParserT, typename ScannerT, typename BinaryT, 190 typename NestedT 191 > 192 static typename parser_result<ParserT, ScannerT>::type 193 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, 194 NestedT const& nested_d) 195 { 196 return nested_d[binary].parse(scan); 197 } 198 }; 199 200 template <> 201 struct refactor_action_nested<action_parser_category> { 202 203 template < 204 typename ParserT, typename ScannerT, typename BinaryT, 205 typename NestedT 206 > 207 static typename parser_result<ParserT, ScannerT>::type 208 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, 209 NestedT const& nested_d) 210 { 211 typedef typename BinaryT::parser_generator_t binary_gen_t; 212 213 return ( 214 nested_d[ 215 binary_gen_t::generate( 216 binary.left().subject(), 217 binary.right() 218 ) 219 ][binary.left().predicate()] 220 ).parse(scan); 221 } 222 }; 223 224 /////////////////////////////////////////////////////////////////////////// 225 template <typename CategoryT> 226 struct refactor_action_non_nested { 227 228 template <typename ParserT, typename ScannerT, typename BinaryT> 229 static typename parser_result<ParserT, ScannerT>::type 230 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) 231 { 232 return binary.parse(scan); 233 } 234 }; 235 236 template <> 237 struct refactor_action_non_nested<action_parser_category> { 238 239 template <typename ParserT, typename ScannerT, typename BinaryT> 240 static typename parser_result<ParserT, ScannerT>::type 241 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) 242 { 243 typedef typename BinaryT::parser_generator_t binary_gen_t; 244 245 return ( 246 binary_gen_t::generate( 247 binary.left().subject(), 248 binary.right() 249 )[binary.left().predicate()] 250 ).parse(scan); 251 } 252 }; 253 254 /////////////////////////////////////////////////////////////////////////// 255 template <typename NestedT> 256 struct refactor_action_type { 257 258 template <typename ParserT, typename ScannerT, typename BinaryT> 259 static typename parser_result<ParserT, ScannerT>::type 260 parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, 261 NestedT const& nested_d) 262 { 263 typedef 264 typename BinaryT::left_t::parser_category_t 265 parser_category_t; 266 267 return refactor_action_nested<parser_category_t>:: 268 parse(p, scan, binary, nested_d); 269 } 270 }; 271 272 template <> 273 struct refactor_action_type<non_nested_refactoring> { 274 275 template <typename ParserT, typename ScannerT, typename BinaryT> 276 static typename parser_result<ParserT, ScannerT>::type 277 parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, 278 non_nested_refactoring const&) 279 { 280 typedef 281 typename BinaryT::left_t::parser_category_t 282 parser_category_t; 283 284 return refactor_action_non_nested<parser_category_t>:: 285 parse(p, scan, binary); 286 } 287 }; 288 289 template <> 290 struct refactor_action_type<self_nested_refactoring> { 291 292 template <typename ParserT, typename ScannerT, typename BinaryT> 293 static typename parser_result<ParserT, ScannerT>::type 294 parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, 295 self_nested_refactoring const &nested_tag) 296 { 297 typedef typename ParserT::parser_generator_t parser_generator_t; 298 typedef 299 typename BinaryT::left_t::parser_category_t 300 parser_category_t; 301 302 parser_generator_t nested_d(nested_tag); 303 return refactor_action_nested<parser_category_t>:: 304 parse(p, scan, binary, nested_d); 305 } 306 }; 307 308 /////////////////////////////////////////////////////////////////////////// 309 // 310 // refactor the action attached to a binary parser 311 // 312 // The refactoring should be done only if the given parser is an 313 // binary_parser_category parser. 314 // 315 /////////////////////////////////////////////////////////////////////////// 316 317 /////////////////////////////////////////////////////////////////////////// 318 template <typename CategoryT> 319 struct attach_action_nested { 320 321 template < 322 typename ParserT, typename ScannerT, typename ActionT, 323 typename NestedT 324 > 325 static typename parser_result<ParserT, ScannerT>::type 326 parse(ParserT const &, ScannerT const& scan, ActionT const &action, 327 NestedT const& /*nested_d*/) 328 { 329 return action.parse(scan); 330 } 331 }; 332 333 template <> 334 struct attach_action_nested<binary_parser_category> { 335 336 template < 337 typename ParserT, typename ScannerT, typename ActionT, 338 typename NestedT 339 > 340 static typename parser_result<ParserT, ScannerT>::type 341 parse(ParserT const &, ScannerT const& scan, ActionT const &action, 342 NestedT const& nested_d) 343 { 344 typedef 345 typename ActionT::subject_t::parser_generator_t 346 binary_gen_t; 347 348 return ( 349 binary_gen_t::generate( 350 nested_d[action.subject().left()[action.predicate()]], 351 nested_d[action.subject().right()[action.predicate()]] 352 ) 353 ).parse(scan); 354 } 355 }; 356 357 /////////////////////////////////////////////////////////////////////////// 358 template <typename CategoryT> 359 struct attach_action_non_nested { 360 361 template <typename ParserT, typename ScannerT, typename ActionT> 362 static typename parser_result<ParserT, ScannerT>::type 363 parse(ParserT const &, ScannerT const& scan, ActionT const &action) 364 { 365 return action.parse(scan); 366 } 367 }; 368 369 template <> 370 struct attach_action_non_nested<binary_parser_category> { 371 372 template <typename ParserT, typename ScannerT, typename ActionT> 373 static typename parser_result<ParserT, ScannerT>::type 374 parse(ParserT const &, ScannerT const& scan, ActionT const &action) 375 { 376 typedef 377 typename ActionT::subject_t::parser_generator_t 378 binary_gen_t; 379 380 return ( 381 binary_gen_t::generate( 382 action.subject().left()[action.predicate()], 383 action.subject().right()[action.predicate()] 384 ) 385 ).parse(scan); 386 } 387 }; 388 389 /////////////////////////////////////////////////////////////////////////// 390 template <typename NestedT> 391 struct attach_action_type { 392 393 template <typename ParserT, typename ScannerT, typename ActionT> 394 static typename parser_result<ParserT, ScannerT>::type 395 parse(ParserT const &p, ScannerT const& scan, ActionT const& action, 396 NestedT const& nested_d) 397 { 398 typedef 399 typename ActionT::subject_t::parser_category_t 400 parser_category_t; 401 402 return attach_action_nested<parser_category_t>:: 403 parse(p, scan, action, nested_d); 404 } 405 }; 406 407 template <> 408 struct attach_action_type<non_nested_refactoring> { 409 410 template <typename ParserT, typename ScannerT, typename ActionT> 411 static typename parser_result<ParserT, ScannerT>::type 412 parse(ParserT const &p, ScannerT const& scan, ActionT const &action, 413 non_nested_refactoring const&) 414 { 415 typedef 416 typename ActionT::subject_t::parser_category_t 417 parser_category_t; 418 419 return attach_action_non_nested<parser_category_t>:: 420 parse(p, scan, action); 421 } 422 }; 423 424 template <> 425 struct attach_action_type<self_nested_refactoring> { 426 427 template <typename ParserT, typename ScannerT, typename ActionT> 428 static typename parser_result<ParserT, ScannerT>::type 429 parse(ParserT const &p, ScannerT const& scan, ActionT const &action, 430 self_nested_refactoring const& nested_tag) 431 { 432 typedef typename ParserT::parser_generator_t parser_generator_t; 433 typedef 434 typename ActionT::subject_t::parser_category_t 435 parser_category_t; 436 437 parser_generator_t nested_d(nested_tag); 438 return attach_action_nested<parser_category_t>:: 439 parse(p, scan, action, nested_d); 440 } 441 }; 442 443} // namespace impl 444 445/////////////////////////////////////////////////////////////////////////////// 446BOOST_SPIRIT_CLASSIC_NAMESPACE_END 447 448}} // namespace boost::spirit 449 450#endif 451 452