What it is
nom is a parser combinator library for Rust that builds parsers from small composable functions, working on bytes or strings with zero copying.
Each parser takes input and returns the remaining input plus a value. Combinators sequence, alternate and repeat them into a complete grammar.
Installation
cargo add nomGetting started
The smallest useful thing you can do with it, and what each part means.
rust
use nom::{
IResult, Parser,
bytes::complete::tag,
character::complete::{digit1, space0},
sequence::separated_pair,
combinator::map_res,
};
fn number(input: &str) -> IResult<&str, u32> {
map_res(digit1, str::parse).parse(input)
}
// Parses "12x34" into (12, 34)
fn dimensions(input: &str) -> IResult<&str, (u32, u32)> {
separated_pair(number, tag("x"), number).parse(input)
}
let (rest, (w, h)) = dimensions("1920x1080")?;Advanced usage
Where the library earns its place over a simpler alternative.
rust
use nom::{branch::alt, multi::separated_list0, sequence::delimited};
#[derive(Debug)]
enum Value { Num(f64), Text(String), List(Vec<Value>) }
fn value(input: &str) -> IResult<&str, Value> {
alt((
map(double, Value::Num),
map(quoted_string, Value::Text),
map(list, Value::List),
)).parse(input)
}
fn list(input: &str) -> IResult<&str, Vec<Value>> {
delimited(
(tag("["), space0),
separated_list0((tag(","), space0), value),
(space0, tag("]")),
).parse(input)
}
// For readable failures, use VerboseError and convert_error.Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- Parser succeeds but leaves input unconsumed
- Wrap the top-level parser in all_consuming so trailing junk is an error.
- Compile errors after upgrading
- nom 8 moved to a Parser trait with .parse(); the old function-call style no longer compiles. Check the version an example targets.
Best practices
- Build small named parsers and unit-test them individually.
- Use VerboseError plus convert_error for diagnostics; the default error type is terse by design.
- Order alt branches from most to least specific.
- Check that all input was consumed — a parser succeeding on a prefix is a common oversight.
Background
Why it exists, and what it was reacting to.
nom is used wherever Rust needs to parse a format — network protocols, file headers, configuration languages. Combinators mean each piece is independently testable rather than one large state machine.
