1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! Support for whitespace delimited formats
//!
//! a lot of textual formats allows spaces and other
//! types of separators between tokens. Handling it
//! manually with nom means wrapping all parsers
//! like this:
//!
//! ```ignore
//! named!(token, delimited!(space, tk, space));
//! ```
//!
//! To ease the development of such parsers, you
//! can use the whitespace parsing facility, which works
//! as follows:
//!
//! ```
//! # #[macro_use] extern crate nom;
//! # fn main() {
//! named!(tuple<&[u8], (&[u8], &[u8]) >,
//!   ws!(tuple!( take!(3), tag!("de") ))
//! );
//!
//! assert_eq!(
//!   tuple(&b" \t abc de fg"[..]),
//!  Ok((&b"fg"[..], (&b"abc"[..], &b"de"[..])))
//! );
//! # }
//! ```
//!
//! The `ws!` combinator will modify the parser to
//! intersperse space parsers everywhere. By default,
//! it will consume the following characters: `" \t\r\n"`.
//!
//! If you want to modify that behaviour, you can make
//! your own whitespace wrapper. As an example, if
//! you don't want to consume ends of lines, only
//! spaces and tabs, you can do it like this:
//!
//! ```
//! # #[macro_use] extern crate nom;
//! named!(pub space, eat_separator!(&b" \t"[..]));
//!
//! #[macro_export]
//! macro_rules! sp (
//!   ($i:expr, $($args:tt)*) => (
//!     {
//!       use nom::Convert;
//!       use nom::Err;
//!
//!       match sep!($i, space, $($args)*) {
//!         Err(e) => Err(e),
//!         Ok((i1,o))    => {
//!           match space(i1) {
//!             Err(e) => Err(Err::convert(e)),
//!             Ok((i2,_))    => Ok((i2, o))
//!           }
//!         }
//!       }
//!     }
//!   )
//! );
//!
//! # fn main() {
//! named!(tuple<&[u8], (&[u8], &[u8]) >,
//!   sp!(tuple!( take!(3), tag!("de") ))
//! );
//!
//! assert_eq!(
//!   tuple(&b" \t abc de fg"[..]),
//!  Ok((&b"fg"[..], (&b"abc"[..], &b"de"[..])))
//! );
//! # }
//! ```
//!
//! This combinator works by replacing each combinator with
//! a version that supports wrapping with separator parsers.
//! It will not support the combinators you wrote in your
//! own code. You can still manually wrap them with the separator
//! you want, or you can copy the macros defined in src/whitespace.rs
//! and modify them to support a new combinator:
//!
//! * copy the combinator's code here, add the _sep suffix
//! * add the `$separator:expr` as second argument
//! * wrap any sub parsers with sep!($separator, $submac!($($args)*))
//! * reference it in the definition of `sep!` as follows:
//!
//! ```ignore
//!  ($i:expr,  $separator:path, my_combinator ! ($($rest:tt)*) ) => {
//!    wrap_sep!($i,
//!      $separator,
//!      my_combinator_sep!($separator, $($rest)*)
//!    )
//!  };
//! ```
//!
#![cfg_attr(not(feature = "std"), no_std)]

#[macro_use]
extern crate nom;

pub mod lib {
  #[cfg(not(feature = "std"))]
  pub mod std {
    pub use core::{option, result};
  }

  #[cfg(feature = "std")]
  pub mod std {
    pub use std::{option, result};
  }

  pub mod nom {
    pub use nom::{Err,Convert,IResult,ErrorKind, AsChar, FindToken, InputTakeAtPosition};
  }
}

pub use self::whitespace::*;

#[macro_use]
mod whitespace;