commit | f3f7e4ebc152cb84e657db408f4d90fec44c20f5 | [log] [tgz] |
---|---|---|
author | Thiébaud Weksteen <tweek@google.com> | Mon Jun 21 20:59:32 2021 +0200 |
committer | Thiébaud Weksteen <tweek@google.com> | Tue Jun 22 07:14:19 2021 +0000 |
tree | 1890b58e5d2b5643016d6e2e9b99b6f56ac42127 | |
parent | af89f69863b5e89257fde5e0598ba3b1fe2ac06a [diff] |
Update to 6.2.0 Add patch to avoid requiring bitvec and its dependencies[1]. [1] https://github.com/Geal/nom/pull/1325 Bug: 178357400 Change-Id: I07c2b3926192d3b31e5971437bba86d5c7be35df
nom is a parser combinators library written in Rust. Its goal is to provide tools to build safe parsers without compromising the speed or memory consumption. To that end, it uses extensively Rust's strong typing and memory safety to produce fast and correct parsers, and provides functions, macros and traits to abstract most of the error prone plumbing.
nom will happily take a byte out of your files :)
Hexadecimal color parser:
extern crate nom; use nom::{ IResult, bytes::complete::{tag, take_while_m_n}, combinator::map_res, sequence::tuple }; #[derive(Debug,PartialEq)] pub struct Color { pub red: u8, pub green: u8, pub blue: u8, } fn from_hex(input: &str) -> Result<u8, std::num::ParseIntError> { u8::from_str_radix(input, 16) } fn is_hex_digit(c: char) -> bool { c.is_digit(16) } fn hex_primary(input: &str) -> IResult<&str, u8> { map_res( take_while_m_n(2, 2, is_hex_digit), from_hex )(input) } fn hex_color(input: &str) -> IResult<&str, Color> { let (input, _) = tag("#")(input)?; let (input, (red, green, blue)) = tuple((hex_primary, hex_primary, hex_primary))(input)?; Ok((input, Color { red, green, blue })) } fn main() {} #[test] fn parse_color() { assert_eq!(hex_color("#2F14DF"), Ok(("", Color { red: 47, green: 20, blue: 223, }))); }
If you need any help developing your parsers, please ping geal
on IRC (freenode, geeknode, oftc), go to #nom-parsers
on Freenode IRC, or on the Gitter chat room.
If you want to write:
nom was designed to properly parse binary formats from the beginning. Compared to the usual handwritten C parsers, nom parsers are just as fast, free from buffer overflow vulnerabilities, and handle common patterns for you:
Example projects:
While nom was made for binary format at first, it soon grew to work just as well with text formats. From line based formats like CSV, to more complex, nested formats such as JSON, nom can manage it, and provides you with useful tools:
Example projects:
While programming language parsers are usually written manually for more flexibility and performance, nom can be (and has been successfully) used as a prototyping parser for a language.
nom will get you started quickly with powerful custom error types, that you can leverage with nom_locate to pinpoint the exact line and column of the error. No need for separate tokenizing, lexing and parsing phases: nom can automatically handle whitespace parsing, and construct an AST in place.
Example projects:
While a lot of formats (and the code handling them) assume that they can fit the complete data in memory, there are formats for which we only get a part of the data at once, like network formats, or huge files. nom has been designed for a correct behaviour with partial data: If there is not enough data to decide, nom will tell you it needs more instead of silently returning a wrong result. Whether your data comes entirely or in chunks, the result should be the same.
It allows you to build powerful, deterministic state machines for your protocols.
Example projects:
Parser combinators are an approach to parsers that is very different from software like lex and yacc. Instead of writing the grammar in a separate file and generating the corresponding code, you use very small functions with very specific purpose, like “take 5 bytes”, or “recognize the word ‘HTTP’”, and assemble them in meaningful patterns like “recognize ‘HTTP’, then a space, then a version”. The resulting code is small, and looks like the grammar you would have written with other parser approaches.
This has a few advantages:
nom parsers are for:
&[u8]
and parsers will work as much as possible on byte array slices (but are not limited to them)Some benchmarks are available on Github.
The 6.0 series of nom requires Rustc version 1.44 or greater (compatible with 1.37 if building without the alloc
or std
features, ie --no-default-features --features="regex,lexical"
).
Travis CI always has a build with a pinned version of Rustc matching the oldest supported Rust release. The current policy is that this will only be updated in the next major nom release.
nom is available on crates.io and can be included in your Cargo enabled project like this:
[dependencies] nom = "6"
Then include it in your code like this:
#[macro_use] extern crate nom;
NOTE: If you have existing code using nom below the 5.0 version, please take a look at the upgrade documentation to handle the breaking changes.
There are a few compilation features:
std
: (activated by default) if disabled, nom can work in no_std
buildsregexp
: Enables regular expression parsers with the regex
crateYou can activate those features like this:
[dependencies.nom] version = "6" features = ["regexp"]
Here is a (non exhaustive) list of known projects using nom:
Want to create a new parser using nom
? A list of not yet implemented formats is available here.
Want to add your parser here? Create a pull request for it!
nom is the fruit of the work of many contributors over the years, many thanks for your help!