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)*)
//! )
//! };
//! ```
//!
extern crate nom;
pub use *;