Crate nom [] [src]

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

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 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);
}

Reexports

pub use self::util::*;
pub use self::internal::*;
pub use self::macros::*;
pub use self::producer::*;
pub use self::consumer::*;
pub use self::nom::*;

Modules

consumer

Data consumers

internal

Basic types to build the parsers

macros

Macro combinators

nom

Useful parser combinators

producer

Data producers

util

Macros

alt!

try a list of parser, return the result of the first successful one

alt_parser!

Internal parser, do not use directly

call!

Used to wrap common expressions and function as macros

chain!

chains parsers and assemble the results through a closure

chaining_parser!

Internal parser, do not use directly

closure!

Wraps a parser in a closure

cond!

Conditional combinator

count!

Applies the child parser a specified number of times

dbg!

Prints a message if the parser fails

dbg_dmp!

Prints a message and the input if the parser fails

delimited!

delimited(opening, X, closing) returns X

error!

Prevents backtracking if the child parser fails

filter!

returns the longest list of bytes until the provided parser fails

flat_map!

flat_map! combines a parser R -> IResult and a parser S -> IResult to return another parser R -> IResult

is_a!

returns the longest list of bytes that appear in the provided array

is_not!

returns the longest list of bytes that do not appear in the provided array

length_value!

returns

many0!

Applies the parser 0 or more times and returns the list of results in a Vec

many1!

Applies the parser 1 or more times and returns the list of results in a Vec

map!

maps a function on the result of a parser

map_opt!

maps a function returning an Option on the output of a parser

map_res!

maps a function returning a Result on the output of a parser

named!

Makes a function from a parser combination

opt!

make the underlying parser optional

pair!

pair(X,Y), returns (x,y)

peek!

returns a result without consuming the input

preceded!

preceded(opening, X) returns X

pusher!

Prepares a parser function for a push pipeline

separated_list!

separated_list(sep, X) returns Vec

separated_nonempty_list!

separated_nonempty_list(sep, X) returns Vec

separated_pair!

separated_pair(X,sep,Y) returns (x,y)

tag!

declares a byte array as a suite to recognize

take!

generates a parser consuming the specified number of bytes

take_until!
take_until_and_consume!

generates a parser consuming bytes until the specified byte sequence is found

take_until_either!
take_until_either_and_consume!
terminated!

terminated(X, closing) returns X