1 //! Support for whitespace delimited formats 2 //! 3 //! a lot of textual formats allows spaces and other 4 //! types of separators between tokens. Handling it 5 //! manually with nom means wrapping all parsers 6 //! like this: 7 //! 8 //! ```ignore 9 //! named!(token, delimited!(space, tk, space)); 10 //! ``` 11 //! 12 //! To ease the development of such parsers, you 13 //! can use the whitespace parsing facility, which works 14 //! as follows: 15 //! 16 //! ``` 17 //! # #[macro_use] extern crate nom; 18 //! # fn main() { 19 //! named!(tuple<&[u8], (&[u8], &[u8]) >, 20 //! ws!(tuple!( take!(3), tag!("de") )) 21 //! ); 22 //! 23 //! assert_eq!( 24 //! tuple(&b" \t abc de fg"[..]), 25 //! Ok((&b"fg"[..], (&b"abc"[..], &b"de"[..]))) 26 //! ); 27 //! # } 28 //! ``` 29 //! 30 //! The `ws!` combinator will modify the parser to 31 //! intersperse space parsers everywhere. By default, 32 //! it will consume the following characters: `" \t\r\n"`. 33 //! 34 //! If you want to modify that behaviour, you can make 35 //! your own whitespace wrapper. As an example, if 36 //! you don't want to consume ends of lines, only 37 //! spaces and tabs, you can do it like this: 38 //! 39 //! ``` 40 //! # #[macro_use] extern crate nom; 41 //! named!(pub space, eat_separator!(&b" \t"[..])); 42 //! 43 //! #[macro_export] 44 //! macro_rules! sp ( 45 //! ($i:expr, $($args:tt)*) => ( 46 //! { 47 //! use nom::Err; 48 //! 49 //! match sep!($i, space, $($args)*) { 50 //! Err(e) => Err(e), 51 //! Ok((i1,o)) => { 52 //! match space(i1) { 53 //! Err(e) => Err(Err::convert(e)), 54 //! Ok((i2,_)) => Ok((i2, o)) 55 //! } 56 //! } 57 //! } 58 //! } 59 //! ) 60 //! ); 61 //! 62 //! # fn main() { 63 //! named!(tuple<&[u8], (&[u8], &[u8]) >, 64 //! sp!(tuple!( take!(3), tag!("de") )) 65 //! ); 66 //! 67 //! assert_eq!( 68 //! tuple(&b" \t abc de fg"[..]), 69 //! Ok((&b"fg"[..], (&b"abc"[..], &b"de"[..]))) 70 //! ); 71 //! # } 72 //! ``` 73 //! 74 //! This combinator works by replacing each combinator with 75 //! a version that supports wrapping with separator parsers. 76 //! It will not support the combinators you wrote in your 77 //! own code. You can still manually wrap them with the separator 78 //! you want, or you can copy the macros defined in src/whitespace.rs 79 //! and modify them to support a new combinator: 80 //! 81 //! * copy the combinator's code here, add the _sep suffix 82 //! * add the `$separator:expr` as second argument 83 //! * wrap any sub parsers with sep!($separator, $submac!($($args)*)) 84 //! * reference it in the definition of `sep!` as follows: 85 //! 86 //! ```ignore 87 //! ($i:expr, $separator:path, my_combinator ! ($($rest:tt)*) ) => { 88 //! wrap_sep!($i, 89 //! $separator, 90 //! my_combinator_sep!($separator, $($rest)*) 91 //! ) 92 //! }; 93 //! ``` 94 //! 95 96 /// applies the separator parser before the other parser 97 #[macro_export(local_inner_macros)] 98 macro_rules! wrap_sep ( 99 ($i:expr, $separator:expr, $submac:ident!( $($args:tt)* )) => ({ 100 use $crate::lib::std::result::Result::*; 101 use $crate::{Err,IResult}; 102 103 fn unify_types<I,O,P,E>(_: &IResult<I,O,E>, _: &IResult<I,P,E>) {} 104 105 let sep_res = ($separator)($i); 106 match sep_res { 107 Ok((i1,_)) => { 108 let res = $submac!(i1, $($args)*); 109 unify_types(&sep_res, &res); 110 res 111 }, 112 Err(e) => Err(Err::convert(e)), 113 } 114 }); 115 ($i:expr, $separator:expr, $f:expr) => ( 116 wrap_sep!($i, $separator, call!($f)) 117 ); 118 ); 119 120 #[doc(hidden)] 121 #[macro_export(local_inner_macros)] 122 macro_rules! pair_sep ( 123 ($i:expr, $separator:path, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => ( 124 tuple!( 125 $i, 126 sep!($separator, $submac!($($args)*)), 127 sep!($separator, $submac2!($($args2)*)) 128 ) 129 ); 130 ($i:expr, $separator:path, $submac:ident!( $($args:tt)* ), $g:expr) => ( 131 pair_sep!($i, $separator, $submac!($($args)*), call!($g)); 132 ); 133 ($i:expr, $separator:path, $f:expr, $submac:ident!( $($args:tt)* )) => ( 134 pair_sep!($i, $separator, call!($f), $submac!($($args)*)); 135 ); 136 ($i:expr, $separator:path, $f:expr, $g:expr) => ( 137 pair_sep!($i, $separator, call!($f), call!($g)); 138 ); 139 ); 140 141 #[doc(hidden)] 142 #[macro_export(local_inner_macros)] 143 macro_rules! delimited_sep ( 144 ($i:expr, $separator:path, $submac1:ident!( $($args1:tt)* ), $($rest:tt)+) => ({ 145 use $crate::lib::std::result::Result::*; 146 147 match tuple_sep!($i, $separator, (), $submac1!($($args1)*), $($rest)+) { 148 Err(e) => Err(e), 149 Ok((remaining, (_,o,_))) => { 150 Ok((remaining, o)) 151 } 152 } 153 }); 154 ($i:expr, $separator:path, $f:expr, $($rest:tt)+) => ( 155 delimited_sep!($i, $separator, call!($f), $($rest)+); 156 ); 157 ); 158 159 #[doc(hidden)] 160 #[macro_export(local_inner_macros)] 161 macro_rules! separated_pair_sep ( 162 ($i:expr, $separator:path, $submac1:ident!( $($args1:tt)* ), $($rest:tt)+) => ({ 163 use $crate::lib::std::result::Result::*; 164 165 match tuple_sep!($i, $separator, (), $submac1!($($args1)*), $($rest)+) { 166 Err(e) => Err(e), 167 Ok((remaining, (o1,_,o2))) => { 168 Ok((remaining, (o1,o2))) 169 } 170 } 171 }); 172 ($i:expr, $separator:path, $f:expr, $($rest:tt)+) => ( 173 separated_pair_sep!($i, $separator, call!($f), $($rest)+); 174 ); 175 ); 176 177 #[doc(hidden)] 178 #[macro_export(local_inner_macros)] 179 macro_rules! preceded_sep ( 180 ($i:expr, $separator:path, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => ({ 181 use $crate::lib::std::result::Result::*; 182 183 match pair_sep!($i, $separator, $submac!($($args)*), $submac2!($($args2)*)) { 184 Err(e) => Err(e), 185 Ok((remaining, (_,o))) => { 186 Ok((remaining, o)) 187 } 188 } 189 }); 190 ($i:expr, $separator:path, $submac:ident!( $($args:tt)* ), $g:expr) => ( 191 preceded_sep!($i, $separator, $submac!($($args)*), call!($g)); 192 ); 193 ($i:expr, $separator:path, $f:expr, $submac:ident!( $($args:tt)* )) => ( 194 preceded_sep!($i, $separator, call!($f), $submac!($($args)*)); 195 ); 196 ($i:expr, $separator:path, $f:expr, $g:expr) => ( 197 preceded_sep!($i, $separator, call!($f), call!($g)); 198 ); 199 ); 200 201 #[doc(hidden)] 202 #[macro_export(local_inner_macros)] 203 macro_rules! terminated_sep ( 204 ($i:expr, $separator:path, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => ({ 205 use $crate::lib::std::result::Result::*; 206 207 match pair_sep!($i, $separator, $submac!($($args)*), $submac2!($($args2)*)) { 208 Err(e) => Err(e), 209 Ok((remaining, (o,_))) => { 210 Ok((remaining, o)) 211 } 212 } 213 }); 214 ($i:expr, $separator:path, $submac:ident!( $($args:tt)* ), $g:expr) => ( 215 terminated_sep!($i, $separator, $submac!($($args)*), call!($g)); 216 ); 217 ($i:expr, $separator:path, $f:expr, $submac:ident!( $($args:tt)* )) => ( 218 terminated_sep!($i, $separator, call!($f), $submac!($($args)*)); 219 ); 220 ($i:expr, $separator:path, $f:expr, $g:expr) => ( 221 terminated_sep!($i, $separator, call!($f), call!($g)); 222 ); 223 ); 224 225 /// Internal parser, do not use directly 226 #[doc(hidden)] 227 #[macro_export(local_inner_macros)] 228 macro_rules! tuple_sep ( 229 ($i:expr, $separator:path, ($($parsed:tt),*), $e:path, $($rest:tt)*) => ( 230 tuple_sep!($i, $separator, ($($parsed),*), call!($e), $($rest)*); 231 ); 232 ($i:expr, $separator:path, (), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ( 233 { 234 use $crate::lib::std::result::Result::*; 235 236 match sep!($i, $separator, $submac!($($args)*)) { 237 Err(e) => Err(e), 238 Ok((i,o)) => { 239 tuple_sep!(i, $separator, (o), $($rest)*) 240 } 241 } 242 } 243 ); 244 ($i:expr, $separator:path, ($($parsed:tt)*), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ( 245 { 246 use $crate::lib::std::result::Result::*; 247 248 match sep!($i, $separator, $submac!($($args)*)) { 249 Err(e) => Err(e), 250 Ok((i,o)) => { 251 tuple_sep!(i, $separator, ($($parsed)* , o), $($rest)*) 252 } 253 } 254 } 255 ); 256 ($i:expr, $separator:path, ($($parsed:tt),*), $e:path) => ( 257 tuple_sep!($i, $separator, ($($parsed),*), call!($e)); 258 ); 259 ($i:expr, $separator:path, (), $submac:ident!( $($args:tt)* )) => ( 260 { 261 use $crate::lib::std::result::Result::*; 262 263 match sep!($i, $separator, $submac!($($args)*)) { 264 Err(e) => Err(e), 265 Ok((i,o)) => { 266 Ok((i, (o))) 267 } 268 } 269 } 270 ); 271 ($i:expr, $separator:path, ($($parsed:expr),*), $submac:ident!( $($args:tt)* )) => ( 272 { 273 use $crate::lib::std::result::Result::*; 274 275 match sep!($i, $separator, $submac!($($args)*)) { 276 Err(e) => Err(e), 277 Ok((i,o)) => { 278 Ok((i, ($($parsed),* , o))) 279 } 280 } 281 } 282 ); 283 ($i:expr, $separator:path, ($($parsed:expr),*)) => ( 284 { 285 ::sts::result::Result::Ok(($i, ($($parsed),*))) 286 } 287 ); 288 ); 289 290 #[doc(hidden)] 291 #[macro_export(local_inner_macros)] 292 macro_rules! do_parse_sep ( 293 (__impl $i:expr, $separator:path, ( $($rest:expr),* )) => ( 294 $crate::lib::std::result::Result::Ok(($i, ( $($rest),* ))) 295 ); 296 297 (__impl $i:expr, $separator:path, $e:ident >> $($rest:tt)*) => ( 298 do_parse_sep!(__impl $i, $separator, call!($e) >> $($rest)*); 299 ); 300 (__impl $i:expr, $separator:path, $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => ( 301 { 302 use $crate::lib::std::result::Result::*; 303 304 match sep!($i, $separator, $submac!($($args)*)) { 305 Err(e) => Err(e), 306 Ok((i,_)) => { 307 do_parse_sep!(__impl i, $separator, $($rest)*) 308 }, 309 } 310 } 311 ); 312 313 (__impl $i:expr, $separator:path, $field:ident : $e:ident >> $($rest:tt)*) => ( 314 do_parse_sep!(__impl $i, $separator, $field: call!($e) >> $($rest)*); 315 ); 316 317 (__impl $i:expr, $separator:path, $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => ( 318 { 319 use $crate::lib::std::result::Result::*; 320 321 match sep!($i, $separator, $submac!($($args)*)) { 322 Err(e) => Err(e), 323 Ok((i,o)) => { 324 let $field = o; 325 do_parse_sep!(__impl i, $separator, $($rest)*) 326 }, 327 } 328 } 329 ); 330 331 // ending the chain 332 (__impl $i:expr, $separator:path, $e:ident >> ( $($rest:tt)* )) => ( 333 do_parse_sep!(__impl $i, $separator, call!($e) >> ( $($rest)* )); 334 ); 335 336 (__impl $i:expr, $separator:path, $submac:ident!( $($args:tt)* ) >> ( $($rest:tt)* )) => ({ 337 use $crate::lib::std::result::Result::*; 338 339 match sep!($i, $separator, $submac!($($args)*)) { 340 Err(e) => Err(e), 341 Ok((i,_)) => { 342 Ok((i, ( $($rest)* ))) 343 }, 344 } 345 }); 346 347 (__impl $i:expr, $separator:path, $field:ident : $e:ident >> ( $($rest:tt)* )) => ( 348 do_parse_sep!(__impl $i, $separator, $field: call!($e) >> ( $($rest)* ) ); 349 ); 350 351 (__impl $i:expr, $separator:path, $field:ident : $submac:ident!( $($args:tt)* ) >> ( $($rest:tt)* )) => ({ 352 use $crate::lib::std::result::Result::*; 353 354 match sep!($i, $separator, $submac!($($args)*)) { 355 Err(e) => Err(e), 356 Ok((i,o)) => { 357 let $field = o; 358 Ok((i, ( $($rest)* ))) 359 }, 360 } 361 }); 362 363 ($i:expr, $separator:path, $($rest:tt)*) => ( 364 { 365 do_parse_sep!(__impl $i, $separator, $($rest)*) 366 } 367 ); 368 ); 369 370 #[doc(hidden)] 371 #[macro_export(local_inner_macros)] 372 macro_rules! permutation_sep ( 373 ($i:expr, $separator:path, $($rest:tt)*) => ( 374 { 375 use $crate::lib::std::result::Result::*; 376 use $crate::lib::std::option::Option::*; 377 use $crate::{Err,error::ErrorKind}; 378 379 let mut res = permutation_init!((), $($rest)*); 380 let mut input = $i; 381 let mut error = None; 382 let mut needed = None; 383 384 loop { 385 let mut all_done = true; 386 permutation_iterator_sep!(0, input, $separator, all_done, needed, res, $($rest)*); 387 388 //if we reach that part, it means none of the parsers were able to read anything 389 if !all_done { 390 //FIXME: should wrap the error returned by the child parser 391 error = Option::Some(error_position!(input, ErrorKind::Permutation)); 392 } 393 break; 394 } 395 396 if let Some(need) = needed { 397 Err(Err::convert(need)) 398 } else { 399 if let Some(unwrapped_res) = { permutation_unwrap!(0, (), res, $($rest)*) } { 400 Ok((input, unwrapped_res)) 401 } else { 402 if let Some(e) = error { 403 Err(Err::Error(error_node_position!($i, ErrorKind::Permutation, e))) 404 } else { 405 Err(Err::Error(error_position!($i, ErrorKind::Permutation))) 406 } 407 } 408 } 409 } 410 ); 411 ); 412 413 #[doc(hidden)] 414 #[macro_export(local_inner_macros)] 415 macro_rules! permutation_iterator_sep ( 416 ($it:tt,$i:expr, $separator:path, $all_done:expr, $needed:expr, $res:expr, $e:ident?, $($rest:tt)*) => ( 417 permutation_iterator_sep!($it, $i, $separator, $all_done, $needed, $res, call!($e), $($rest)*); 418 ); 419 ($it:tt,$i:expr, $separator:path, $all_done:expr, $needed:expr, $res:expr, $e:ident, $($rest:tt)*) => ( 420 permutation_iterator_sep!($it, $i, $separator, $all_done, $needed, $res, call!($e), $($rest)*); 421 ); 422 423 ($it:tt, $i:expr, $separator:path, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => ({ 424 permutation_iterator_sep!($it, $i, $separator, $all_done, $needed, $res, $submac!($($args)*), $($rest)*); 425 }); 426 ($it:tt, $i:expr, $separator:path, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ({ 427 use $crate::lib::std::result::Result::*; 428 use $crate::Err; 429 430 if $res.$it == $crate::lib::std::option::Option::None { 431 match {sep!($i, $separator, $submac!($($args)*))} { 432 Ok((i,o)) => { 433 $i = i; 434 $res.$it = $crate::lib::std::option::Option::Some(o); 435 continue; 436 }, 437 Err(Err::Error(_)) => { 438 $all_done = false; 439 }, 440 Err(e) => { 441 $needed = $crate::lib::std::option::Option::Some(e); 442 break; 443 } 444 }; 445 } 446 succ!($it, permutation_iterator_sep!($i, $separator, $all_done, $needed, $res, $($rest)*)); 447 }); 448 449 ($it:tt,$i:expr, $separator:path, $all_done:expr, $needed:expr, $res:expr, $e:ident?) => ( 450 permutation_iterator_sep!($it, $i, $separator, $all_done, $res, call!($e)); 451 ); 452 ($it:tt,$i:expr, $separator:path, $all_done:expr, $needed:expr, $res:expr, $e:ident) => ( 453 permutation_iterator_sep!($it, $i, $separator, $all_done, $res, call!($e)); 454 ); 455 456 ($it:tt, $i:expr, $separator:path, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* )?) => ({ 457 permutation_iterator_sep!($it, $i, $separator, $all_done, $needed, $res, $submac!($($args)*)); 458 }); 459 ($it:tt, $i:expr, $separator:path, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* )) => ({ 460 use $crate::lib::std::result::Result::*; 461 use $crate::Err; 462 463 if $res.$it == $crate::lib::std::option::Option::None { 464 match sep!($i, $separator, $submac!($($args)*)) { 465 Ok((i,o)) => { 466 $i = i; 467 $res.$it = $crate::lib::std::option::Option::Some(o); 468 continue; 469 }, 470 Err(Err::Error(_)) => { 471 $all_done = false; 472 }, 473 Err(e) => { 474 $needed = $crate::lib::std::option::Option::Some(e); 475 break; 476 } 477 }; 478 } 479 }); 480 ); 481 482 #[doc(hidden)] 483 #[macro_export(local_inner_macros)] 484 macro_rules! alt_sep ( 485 (__impl $i:expr, $separator:path, $e:path | $($rest:tt)*) => ( 486 alt_sep!(__impl $i, $separator, call!($e) | $($rest)*); 487 ); 488 489 (__impl $i:expr, $separator:path, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => ( 490 { 491 use $crate::lib::std::result::Result::*; 492 use $crate::Err; 493 494 let res = sep!($i, $separator, $subrule!($($args)*)); 495 match res { 496 Ok((_,_)) => res, 497 Err(Err::Error(_)) => alt_sep!(__impl $i, $separator, $($rest)*), 498 Err(e) => Err(e), 499 } 500 } 501 ); 502 503 (__impl $i:expr, $separator:path, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)+) => ( 504 { 505 use $crate::lib::std::result::Result::*; 506 use $crate::Err; 507 508 match sep!($i, $separator, $subrule!( $($args)* )) { 509 Ok((i,o)) => Ok((i,$gen(o))), 510 Err(Err::Error(_)) => { 511 alt_sep!(__impl $i, $separator, $($rest)+) 512 }, 513 Err(e) => Err(e), 514 } 515 } 516 ); 517 518 (__impl $i:expr, $separator:path, $e:path => { $gen:expr } | $($rest:tt)*) => ( 519 alt_sep!(__impl $i, $separator, call!($e) => { $gen } | $($rest)*); 520 ); 521 522 (__impl $i:expr, $separator:path, $e:path => { $gen:expr }) => ( 523 alt_sep!(__impl $i, $separator, call!($e) => { $gen }); 524 ); 525 526 (__impl $i:expr, $separator:path, $subrule:ident!( $($args:tt)* ) => { $gen:expr }) => ( 527 { 528 use $crate::lib::std::result::Result::*; 529 use $crate::Err; 530 531 match sep!($i, $separator, $subrule!( $($args)* )) { 532 Ok((i,o)) => Ok((i,$gen(o))), 533 Err(Err::Error(e)) => { 534 fn unify_types<T>(_: &T, _: &T) {} 535 let e2 = error_position!($i, $crate::error::ErrorKind::Alt); 536 unify_types(&e, &e2); 537 Err(Err::Error(e2)) 538 }, 539 Err(e) => Err(e), 540 } 541 } 542 ); 543 544 (__impl $i:expr, $separator:path, $e:path) => ( 545 alt_sep!(__impl $i, $separator, call!($e)); 546 ); 547 548 (__impl $i:expr, $separator:path, $subrule:ident!( $($args:tt)*)) => ( 549 { 550 use $crate::lib::std::result::Result::*; 551 use $crate::Err; 552 553 match sep!($i, $separator, $subrule!( $($args)* )) { 554 Ok((i,o)) => Ok((i,o)), 555 Err(Err::Error(e)) => { 556 fn unify_types<T>(_: &T, _: &T) {} 557 let e2 = error_position!($i, $crate::error::ErrorKind::Alt); 558 unify_types(&e, &e2); 559 Err(Err::Error(e2)) 560 }, 561 Err(e) => Err(e), 562 } 563 } 564 ); 565 566 (__impl $i:expr) => ({ 567 use $crate::lib::std::result::Result::*; 568 use $crate::{Err,Needed,IResult}; 569 570 Err(Err::Error(error_position!($i, $crate::error::ErrorKind::Alt))) 571 }); 572 573 (__impl $i:expr, $separator:path) => ({ 574 use $crate::lib::std::result::Result::*; 575 use $crate::{Err,Needed,IResult}; 576 577 Err(Err::Error(error_position!($i, $crate::error::ErrorKind::Alt))) 578 }); 579 580 ($i:expr, $separator:path, $($rest:tt)*) => ( 581 { 582 alt_sep!(__impl $i, $separator, $($rest)*) 583 } 584 ); 585 ); 586 587 #[doc(hidden)] 588 #[macro_export(local_inner_macros)] 589 macro_rules! switch_sep ( 590 (__impl $i:expr, $separator:path, $submac:ident!( $($args:tt)* ), $($p:pat => $subrule:ident!( $($args2:tt)* ))|* ) => ( 591 { 592 use $crate::lib::std::result::Result::*; 593 use $crate::Err; 594 595 match sep!($i, $separator, $submac!($($args)*)) { 596 Err(Err::Error(e)) => Err(Err::Error(error_node_position!( 597 $i, $crate::error::ErrorKind::Switch, e 598 ))), 599 Err(Err::Failure(e)) => Err(Err::Failure( 600 error_node_position!($i, $crate::error::ErrorKind::Switch, e))), 601 Err(e) => Err(e), 602 Ok((i, o)) => { 603 match o { 604 $($p => match sep!(i, $separator, $subrule!($($args2)*)) { 605 Err(Err::Error(e)) => Err(Err::Error(error_node_position!( 606 $i, $crate::error::ErrorKind::Switch, e 607 ))), 608 Err(Err::Failure(e)) => Err(Err::Failure( 609 error_node_position!($i, $crate::error::ErrorKind::Switch, e))), 610 a => a, 611 }),*, 612 _ => Err(Err::Error(error_position!($i, $crate::error::ErrorKind::Switch))) 613 } 614 } 615 } 616 } 617 ); 618 ($i:expr, $separator:path, $submac:ident!( $($args:tt)*), $($rest:tt)*) => ( 619 { 620 switch_sep!(__impl $i, $separator, $submac!($($args)*), $($rest)*) 621 } 622 ); 623 ($i:expr, $separator:path, $e:path, $($rest:tt)*) => ( 624 { 625 switch_sep!(__impl $i, $separator, call!($e), $($rest)*) 626 } 627 ); 628 ); 629 630 #[doc(hidden)] 631 #[cfg(feature = "alloc")] 632 #[macro_export(local_inner_macros)] 633 macro_rules! separated_list_sep ( 634 ($i:expr, $separator:path, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => ( 635 separated_list!( 636 $i, 637 sep!($separator, $submac!($($args)*)), 638 sep!($separator, $submac2!($($args2)*)) 639 ) 640 ); 641 ($i:expr, $separator:path, $submac:ident!( $($args:tt)* ), $g:expr) => ( 642 separated_list_sep!($i, $separator, $submac!($($args)*), call!($g)); 643 ); 644 ($i:expr, $separator:path, $f:expr, $submac:ident!( $($args:tt)* )) => ( 645 separated_list_sep!($i, $separator, call!($f), $submac!($($args)*)); 646 ); 647 ($i:expr, $separator:path, $f:expr, $g:expr) => ( 648 separated_list_sep!($i, $separator, call!($f), call!($g)); 649 ); 650 ); 651 652 /// helper macros to build a separator parser 653 /// 654 /// ``` 655 /// # #[macro_use] extern crate nom; 656 /// named!(pub space, eat_separator!(&b" \t"[..])); 657 /// # fn main() {} 658 /// ``` 659 #[macro_export(local_inner_macros)] 660 macro_rules! eat_separator ( 661 ($i:expr, $arr:expr) => ( 662 { 663 use $crate::{FindToken, InputTakeAtPosition}; 664 let input = $i; 665 input.split_at_position(|c| !$arr.find_token(c)) 666 } 667 ); 668 ); 669 670 /// sep is the parser rewriting macro for whitespace separated formats 671 /// 672 /// it takes as argument a space eating function and a parser tree, 673 /// and will intersperse the space parser everywhere 674 /// 675 /// ```ignore 676 /// #[macro_export(local_inner_macros)] 677 /// macro_rules! ws ( 678 /// ($i:expr, $($args:tt)*) => ( 679 /// { 680 /// use sp; 681 /// sep!($i, sp, $($args)*) 682 /// } 683 /// ) 684 /// ); 685 /// ``` 686 #[macro_export(local_inner_macros)] 687 macro_rules! sep ( 688 ($i:expr, $separator:path, tuple ! ($($rest:tt)*) ) => { 689 tuple_sep!($i, $separator, (), $($rest)*) 690 }; 691 ($i:expr, $separator:path, pair ! ($($rest:tt)*) ) => { 692 wrap_sep!($i, 693 $separator, 694 pair_sep!($separator, $($rest)*) 695 ) 696 }; 697 ($i:expr, $separator:path, delimited ! ($($rest:tt)*) ) => { 698 wrap_sep!($i, 699 $separator, 700 delimited_sep!($separator, $($rest)*) 701 ) 702 }; 703 ($i:expr, $separator:path, separated_pair ! ($($rest:tt)*) ) => { 704 wrap_sep!($i, 705 $separator, 706 separated_pair_sep!($separator, $($rest)*) 707 ) 708 }; 709 ($i:expr, $separator:path, preceded ! ($($rest:tt)*) ) => { 710 wrap_sep!($i, 711 $separator, 712 preceded_sep!($separator, $($rest)*) 713 ) 714 }; 715 ($i:expr, $separator:path, terminated ! ($($rest:tt)*) ) => { 716 wrap_sep!($i, 717 $separator, 718 terminated_sep!($separator, $($rest)*) 719 ) 720 }; 721 ($i:expr, $separator:path, do_parse ! ($($rest:tt)*) ) => { 722 wrap_sep!($i, 723 $separator, 724 do_parse_sep!($separator, $($rest)*) 725 ) 726 }; 727 ($i:expr, $separator:path, permutation ! ($($rest:tt)*) ) => { 728 wrap_sep!($i, 729 $separator, 730 permutation_sep!($separator, $($rest)*) 731 ) 732 }; 733 ($i:expr, $separator:path, alt ! ($($rest:tt)*) ) => { 734 wrap_sep!($i, 735 $separator, 736 alt_sep!($separator, $($rest)*) 737 ) 738 }; 739 ($i:expr, $separator:path, switch ! ($($rest:tt)*) ) => { 740 wrap_sep!($i, 741 $separator, 742 switch_sep!($separator, $($rest)*) 743 ) 744 }; 745 ($i:expr, $separator:path, separated_list ! ($($rest:tt)*) ) => { 746 wrap_sep!($i, 747 $separator, 748 separated_list_sep!($separator, $($rest)*) 749 ) 750 }; 751 ($i:expr, $separator:path, many0 ! ($($rest:tt)*) ) => { 752 many0!($i, wrap_sep!($separator, $($rest)*)) 753 }; 754 ($i:expr, $separator:path, many1 ! ($($rest:tt)*) ) => { 755 many1!($i, wrap_sep!($separator, $($rest)*)) 756 }; 757 ($i:expr, $separator:path, return_error!( $($args:tt)* )) => { 758 return_error!($i, wrap_sep!($separator, $($args)*)) 759 }; 760 //FIXME: missing separated_nonempty_list, 761 // many_till, many_m_n, count, count_fixed, fold_many0, fold_many1, 762 // fold_many_m_n 763 ($i:expr, $separator:path, $submac:ident!( $($args:tt)* )) => { 764 wrap_sep!($i, $separator, $submac!($($args)*)) 765 }; 766 ($i:expr, $separator:path, $f:expr) => { 767 wrap_sep!($i, $separator, call!($f)) 768 }; 769 ); 770 771 /// `ws!(I -> IResult<I,O>) => I -> IResult<I, O>` 772 /// 773 /// transforms a parser to automatically consume 774 /// whitespace between each token. By default, 775 /// it takes the following characters: `" \t\r\n"`. 776 /// 777 /// If you need a whitespace parser consuming a 778 /// different set of characters, you can make 779 /// your own by reusing the `sep!` combinator. 780 /// 781 /// To use `ws!`, pass your parser as argument: 782 /// 783 /// ``` 784 /// # #[macro_use] extern crate nom; 785 /// # fn main() { 786 /// named!(tuple<&[u8], (&[u8], &[u8]) >, 787 /// ws!(tuple!( take!(3), tag!("de") )) 788 /// ); 789 /// 790 /// assert_eq!( 791 /// tuple(&b" \t abc de fg"[..]), 792 /// Ok((&b"fg"[..], (&b"abc"[..], &b"de"[..]))) 793 /// ); 794 /// # } 795 /// ``` 796 /// 797 #[macro_export(local_inner_macros)] 798 #[deprecated(since = "5.0.0", note = "whitespace parsing only works with macros and will not be updated anymore")] 799 macro_rules! ws ( 800 ($i:expr, $($args:tt)*) => ( 801 { 802 use $crate::Err; 803 use $crate::lib::std::result::Result::*; 804 use $crate::character::complete::multispace0; 805 806 match sep!($i, multispace0, $($args)*) { 807 Err(e) => Err(e), 808 Ok((i1,o)) => { 809 match (multispace0)(i1) { 810 Err(e) => Err(Err::convert(e)), 811 Ok((i2,_)) => Ok((i2, o)) 812 } 813 } 814 } 815 } 816 ) 817 ); 818 819 #[cfg(test)] 820 #[allow(dead_code)] 821 mod tests { 822 #[cfg(feature = "alloc")] 823 use crate::{ 824 error::ParseError, 825 lib::std::{ 826 string::{String, ToString}, 827 fmt::Debug 828 } 829 }; 830 use crate::internal::{Err, IResult, Needed}; 831 use crate::character::complete::multispace0 as sp; 832 use crate::error::ErrorKind; 833 834 #[test] spaaaaace()835 fn spaaaaace() { 836 assert_eq!(sp::<_,(_,ErrorKind)>(&b" \t abc "[..]), Ok((&b"abc "[..], &b" \t "[..]))); 837 } 838 839 #[test] tag()840 fn tag() { 841 named!(abc, ws!(tag!("abc"))); 842 843 assert_eq!(abc(&b" \t abc def"[..]), Ok((&b"def"[..], &b"abc"[..]))); 844 } 845 846 #[test] pair()847 fn pair() { 848 named!(pair_2<&[u8], (&[u8], &[u8]) >, 849 ws!(pair!( take!(3), tag!("de") )) 850 ); 851 852 assert_eq!( 853 pair_2(&b" \t abc de fg"[..]), 854 Ok((&b"fg"[..], (&b"abc"[..], &b"de"[..]))) 855 ); 856 } 857 858 #[test] preceded()859 fn preceded() { 860 named!(prec<&[u8], &[u8] >, 861 ws!(preceded!( take!(3), tag!("de") )) 862 ); 863 864 assert_eq!(prec(&b" \t abc de fg"[..]), Ok((&b"fg"[..], &b"de"[..]))); 865 } 866 867 #[test] terminated()868 fn terminated() { 869 named!(term<&[u8], &[u8] >, 870 ws!(terminated!( take!(3), tag!("de") )) 871 ); 872 873 assert_eq!(term(&b" \t abc de fg"[..]), Ok((&b"fg"[..], &b"abc"[..]))); 874 } 875 876 #[test] tuple()877 fn tuple() { 878 //trace_macros!(true); 879 named!(tuple_2<&[u8], (&[u8], &[u8]) >, 880 ws!(tuple!( take!(3), tag!("de") )) 881 ); 882 //trace_macros!(false); 883 884 assert_eq!( 885 tuple_2(&b" \t abc de fg"[..]), 886 Ok((&b"fg"[..], (&b"abc"[..], &b"de"[..]))) 887 ); 888 } 889 890 #[test] levels()891 fn levels() { 892 //trace_macros!(true); 893 named!(level_2<&[u8], (&[u8], (&[u8], &[u8])) >, 894 ws!(pair!(take!(3), tuple!( tag!("de"), tag!("fg ") ))) 895 ); 896 //trace_macros!(false); 897 898 assert_eq!( 899 level_2(&b" \t abc de fg \t hi "[..]), 900 Ok((&b"hi "[..], (&b"abc"[..], (&b"de"[..], &b"fg "[..])))) 901 ); 902 } 903 904 #[test] do_parse()905 fn do_parse() { 906 fn ret_int1(i: &[u8]) -> IResult<&[u8], u8> { 907 Ok((i, 1)) 908 }; 909 fn ret_int2(i: &[u8]) -> IResult<&[u8], u8> { 910 Ok((i, 2)) 911 }; 912 913 //trace_macros!(true); 914 named!(do_parser<&[u8], (u8, u8)>, 915 ws!(do_parse!( 916 tag!("abcd") >> 917 opt!(tag!("abcd")) >> 918 aa: ret_int1 >> 919 tag!("efgh") >> 920 bb: ret_int2 >> 921 tag!("efgh") >> 922 (aa, bb) 923 )) 924 ); 925 926 //trace_macros!(false); 927 928 assert_eq!( 929 do_parser(&b"abcd abcd\tefghefghX"[..]), 930 Ok((&b"X"[..], (1, 2))) 931 ); 932 assert_eq!( 933 do_parser(&b"abcd\tefgh efgh X"[..]), 934 Ok((&b"X"[..], (1, 2))) 935 ); 936 assert_eq!( 937 do_parser(&b"abcd ab"[..]), 938 Err(Err::Incomplete(Needed::Size(4))) 939 ); 940 assert_eq!( 941 do_parser(&b" abcd\tefgh\tef"[..]), 942 Err(Err::Incomplete(Needed::Size(4))) 943 ); 944 } 945 946 #[test] permutation()947 fn permutation() { 948 //trace_macros!(true); 949 named!( 950 perm<(&[u8], &[u8], &[u8])>, 951 ws!(permutation!(tag!("abcd"), tag!("efg"), tag!("hi"))) 952 ); 953 //trace_macros!(false); 954 955 let expected = (&b"abcd"[..], &b"efg"[..], &b"hi"[..]); 956 957 let a = &b"abcd\tefg \thijk"[..]; 958 assert_eq!(perm(a), Ok((&b"jk"[..], expected))); 959 let b = &b" efg \tabcdhi jk"[..]; 960 assert_eq!(perm(b), Ok((&b"jk"[..], expected))); 961 let c = &b" hi efg\tabcdjk"[..]; 962 assert_eq!(perm(c), Ok((&b"jk"[..], expected))); 963 964 let d = &b"efg xyzabcdefghi"[..]; 965 assert_eq!( 966 perm(d), 967 Err(Err::Error(error_node_position!( 968 &b"efg xyzabcdefghi"[..], 969 ErrorKind::Permutation, 970 error_position!(&b" xyzabcdefghi"[..], ErrorKind::Permutation) 971 ))) 972 ); 973 974 let e = &b" efg \tabc"[..]; 975 assert_eq!(perm(e), Err(Err::Incomplete(Needed::Size(4)))); 976 } 977 978 #[cfg(feature = "alloc")] 979 #[derive(Debug, Clone, PartialEq)] 980 pub struct ErrorStr(String); 981 982 #[cfg(feature = "alloc")] 983 impl<'a> From<(&'a[u8], ErrorKind)> for ErrorStr { from(i: (&'a[u8], ErrorKind)) -> Self984 fn from(i: (&'a[u8], ErrorKind)) -> Self { 985 ErrorStr(format!("custom error code: {:?}", i)) 986 } 987 } 988 989 #[cfg(feature = "alloc")] 990 impl<'a> From<(&'a str, ErrorKind)> for ErrorStr { from(i: (&'a str, ErrorKind)) -> Self991 fn from(i: (&'a str, ErrorKind)) -> Self { 992 ErrorStr(format!("custom error message: {:?}", i)) 993 } 994 } 995 996 #[cfg(feature = "alloc")] 997 impl<I: Debug> ParseError<I> for ErrorStr { from_error_kind(input: I, kind: ErrorKind) -> Self998 fn from_error_kind(input: I, kind: ErrorKind) -> Self { 999 ErrorStr(format!("custom error message: ({:?}, {:?})", input, kind)) 1000 } 1001 append(input: I, kind: ErrorKind, other: Self) -> Self1002 fn append(input: I, kind: ErrorKind, other: Self) -> Self { 1003 ErrorStr(format!("custom error message: ({:?}, {:?}) - {:?}", input, kind, other)) 1004 } 1005 } 1006 1007 #[cfg(feature = "alloc")] 1008 #[test] alt()1009 fn alt() { 1010 fn work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 1011 Ok((&b""[..], input)) 1012 } 1013 1014 #[allow(unused_variables)] 1015 fn dont_work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 1016 Err(Err::Error(ErrorStr("abcd".to_string()))) 1017 } 1018 1019 fn work2(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 1020 Ok((input, &b""[..])) 1021 } 1022 1023 fn alt1(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 1024 alt!(i, dont_work | dont_work) 1025 } 1026 fn alt2(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 1027 alt!(i, dont_work | work) 1028 } 1029 fn alt3(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 1030 alt!(i, dont_work | dont_work | work2 | dont_work) 1031 } 1032 1033 let a = &b"\tabcd"[..]; 1034 assert_eq!( 1035 alt1(a), 1036 Err(Err::Error(error_position!(a, ErrorKind::Alt))) 1037 ); 1038 assert_eq!(alt2(a), Ok((&b""[..], a))); 1039 assert_eq!(alt3(a), Ok((a, &b""[..]))); 1040 1041 } 1042 1043 named!(str_parse(&str) -> &str, ws!(tag!("test"))); 1044 #[allow(unused_variables)] 1045 #[test] str_test()1046 fn str_test() { 1047 assert_eq!(str_parse(" \n test\t a\nb"), Ok(("a\nb", "test"))); 1048 } 1049 1050 // test whitespace parser generation for alt 1051 named!(space, tag!(" ")); 1052 #[cfg(feature = "alloc")] 1053 named!(pipeline_statement<&[u8], ()>, 1054 ws!( 1055 do_parse!( 1056 tag!("pipeline") >> 1057 attributes: delimited!(char!('{'), 1058 separated_list!(char!(','), alt!( 1059 space | 1060 space 1061 )), 1062 char!('}')) >> 1063 1064 ({ 1065 let _ = attributes; 1066 () 1067 }) 1068 ) 1069 ) 1070 ); 1071 1072 #[cfg(feature = "alloc")] 1073 named!( 1074 fail<&[u8]>, 1075 map!(many_till!(take!(1), ws!(tag!("."))), |(r, _)| r[0]) 1076 ); 1077 } 1078