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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//! Nom, eating data byte by byte
//!
//! The goal is to make a parser combinator library that is safe,
//! supports streaming (push and pull), and as much as possible zero copy.
//!
//! The code is available on [Github](https://github.com/Geal/nom)
//!
//! # Example
//!
//! ```
//! #[macro_use]
//! extern crate nom;
//!
//! use nom::{Consumer,ConsumerState,MemProducer,IResult};
//! use nom::IResult::*;
//!
//! // Parser definition
//!
//! named!( om_parser,                   tag!( "om" ) );
//! named!( nomnom_parser< &[u8], Vec<&[u8]> >, many1!( tag!( "nom" ) ) );
//! named!( end_parser,                  tag!( "kthxbye")  );
//!
//!
//! // Streaming parsing and state machine
//!
//! #[derive(PartialEq,Eq,Debug)]
//! enum State {
//!   Beginning,
//!   Middle,
//!   End,
//!   Done
//! }
//!
//! struct TestConsumer {
//!   state:   State,
//!   counter: usize
//! }
//!
//! impl Consumer for TestConsumer {
//!   fn consume(&mut self, input: &[u8]) -> ConsumerState {
//!     match self.state {
//!       State::Beginning => {
//!         match om_parser(input) {
//!           Error(_)      => ConsumerState::ConsumerError(0),
//!           Incomplete(_) => ConsumerState::Await(0, 2),
//!           Done(_,_)     => {
//!             // "om" was recognized, get to the next state
//!             self.state = State::Middle;
//!             ConsumerState::Await(2, 3)
//!           }
//!         }
//!       },
//!       State::Middle    => {
//!         match nomnom_parser(input) {
//!           Error(a)         => {
//!             // the "nom" parser failed, let's get to the next state
//!             self.state = State::End;
//!             ConsumerState::Await(0, 7)
//!           },
//!           Incomplete(_)    => ConsumerState::Await(0, 3),
//!           Done(i,noms_vec) => {
//!             // we got a few noms, let's count them and continue
//!             self.counter = self.counter + noms_vec.len();
//!             ConsumerState::Await(input.len() - i.len(), 3)
//!           }
//!         }
//!       },
//!       State::End       => {
//!         match end_parser(input) {
//!           Error(_)      => ConsumerState::ConsumerError(0),
//!           Incomplete(_) => ConsumerState::Await(0, 7),
//!           Done(_,_)     => {
//!             // we recognized the suffix, everything was parsed correctly
//!             self.state = State::Done;
//!             ConsumerState::ConsumerDone
//!           }
//!         }
//!       },
//!       State::Done      => {
//!         // this should not be called
//!         ConsumerState::ConsumerError(42)
//!       }
//!     }
//!   }
//!
//!   fn failed(&mut self, error_code: u32) {
//!     println!("failed with error code: {}", error_code);
//!   }
//!
//!   fn end(&mut self) {
//!     println!("we counted {} noms", self.counter);
//!   }
//! }
//!
//! fn main() {
//!   let mut p = MemProducer::new(b"omnomnomnomkthxbye", 4);
//!   let mut c = TestConsumer{state: State::Beginning, counter: 0};
//!   c.run(&mut p);
//!
//!   assert_eq!(c.counter, 3);
//!   assert_eq!(c.state, State::Done);
//! }
//! ```
//!

#![cfg_attr(feature = "core", feature(no_std))]
#![cfg_attr(feature = "core", feature(core))]
#![cfg_attr(feature = "core", feature(collections))]
#![cfg_attr(feature = "core", no_std)]

#[macro_use]
#[cfg(feature = "core")]
extern crate core;
#[cfg(feature = "core")]
extern crate collections;

#[cfg(feature = "core")]
mod std {
#[macro_use]
  pub use core::{fmt, iter, option, ops, slice, mem};
  pub use collections::{boxed, vec, string};
  pub mod prelude {
    pub use core::prelude as v1;
  }
}

pub use self::util::*;
pub use self::internal::*;//{IResult, IResultClosure, GetInput, GetOutput};
pub use self::macros::*;
#[cfg(not(feature = "core"))]
pub use self::producer::*;//{ProducerState,Producer,FileProducer,MemProducer};
#[cfg(not(feature = "core"))]
pub use self::consumer::*;//{ConsumerState,Consumer};

pub use self::nom::*;

#[macro_use] mod util;
mod internal;
#[macro_use] mod macros;

#[macro_use]
#[cfg(not(feature = "core"))]
mod producer;
#[cfg(not(feature = "core"))]
mod consumer;

#[macro_use] mod nom;