nom_whitespace/
lib.rs

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::Convert;
48//!       use nom::Err;
49//!
50//!       match sep!($i, space, $($args)*) {
51//!         Err(e) => Err(e),
52//!         Ok((i1,o))    => {
53//!           match space(i1) {
54//!             Err(e) => Err(Err::convert(e)),
55//!             Ok((i2,_))    => Ok((i2, o))
56//!           }
57//!         }
58//!       }
59//!     }
60//!   )
61//! );
62//!
63//! # fn main() {
64//! named!(tuple<&[u8], (&[u8], &[u8]) >,
65//!   sp!(tuple!( take!(3), tag!("de") ))
66//! );
67//!
68//! assert_eq!(
69//!   tuple(&b" \t abc de fg"[..]),
70//!  Ok((&b"fg"[..], (&b"abc"[..], &b"de"[..])))
71//! );
72//! # }
73//! ```
74//!
75//! This combinator works by replacing each combinator with
76//! a version that supports wrapping with separator parsers.
77//! It will not support the combinators you wrote in your
78//! own code. You can still manually wrap them with the separator
79//! you want, or you can copy the macros defined in src/whitespace.rs
80//! and modify them to support a new combinator:
81//!
82//! * copy the combinator's code here, add the _sep suffix
83//! * add the `$separator:expr` as second argument
84//! * wrap any sub parsers with sep!($separator, $submac!($($args)*))
85//! * reference it in the definition of `sep!` as follows:
86//!
87//! ```ignore
88//!  ($i:expr,  $separator:path, my_combinator ! ($($rest:tt)*) ) => {
89//!    wrap_sep!($i,
90//!      $separator,
91//!      my_combinator_sep!($separator, $($rest)*)
92//!    )
93//!  };
94//! ```
95//!
96#![cfg_attr(not(feature = "std"), no_std)]
97
98#[macro_use]
99extern crate nom;
100
101pub mod lib {
102  #[cfg(not(feature = "std"))]
103  pub mod std {
104    pub use core::{option, result};
105  }
106
107  #[cfg(feature = "std")]
108  pub mod std {
109    pub use std::{option, result};
110  }
111
112  pub mod nom {
113    pub use nom::{Err,Convert,IResult,ErrorKind, AsChar, FindToken, InputTakeAtPosition};
114  }
115}
116
117pub use self::whitespace::*;
118
119#[macro_use]
120mod whitespace;