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;