#parser #nom


Extension of nom to trace parser

14 releases (7 breaking)

0.8.0 Aug 31, 2021
0.7.0 Nov 26, 2020
0.6.2 Jul 9, 2020
0.4.1 Oct 15, 2019
0.2.1 Jul 29, 2019

#80 in Parser tooling

Download history 234/week @ 2021-06-30 411/week @ 2021-07-07 419/week @ 2021-07-14 447/week @ 2021-07-21 322/week @ 2021-07-28 301/week @ 2021-08-04 339/week @ 2021-08-11 521/week @ 2021-08-18 314/week @ 2021-08-25 301/week @ 2021-09-01 400/week @ 2021-09-08 195/week @ 2021-09-15 283/week @ 2021-09-22 281/week @ 2021-09-29 158/week @ 2021-10-06 224/week @ 2021-10-13

1,393 downloads per month
Used in 14 crates (3 directly)


632 lines


Extension of nom to trace parser.

Actions Status Crates.io Docs.rs


  • Tracing parser by colored format
  • Forward/backward call count
  • Folding the specific parsers
  • Histogram/cumulative histogram of parser call count
  • Zero-overhead when trace is disabled



nom must be 5.0.0 or later. nom-tracable can be applied to function-style parser only.

The input type of nom parser must implement Tracable trait. Therefore &str and &[u8] can't be used. You can define a wrapper type of &str or &[u8] and implement Tracable.

nom-tracable is integrated with nom_locate. You can use nom_locate::LocatedSpan<T, TracableInfo> as input type. This implements Tracable in this crate.

Note: T in nom_locate::LocatedSpan<T, TracableInfo> must implement FragmentDisplay. &str and &[u8] implement it in this crate. If you want to use another type as T, you should implement FragmentDisplay for it.


default = []
trace   = ["nom-tracable/trace"]

nom-tracable = "0.8.0"

nom-tracable provides trace feature, and the crate using nom-tracable must provide the feature too. When trace is enabled, trace dump is enabled. If not, there is no additional cost.


You can try examples by the following command.

$ cargo run --manifest-path=nom-tracable/Cargo.toml --example str_parser --features trace
$ cargo run --manifest-path=nom-tracable/Cargo.toml --example u8_parser --features trace

str_parser is below:

use nom::branch::*;
use nom::character::complete::*;
use nom::IResult;
use nom_locate::LocatedSpan;
use nom_tracable::{cumulative_histogram, histogram, tracable_parser, TracableInfo};

// Input type must implement trait Tracable
// nom_locate::LocatedSpan<T, TracableInfo> implements it.
type Span<'a> = LocatedSpan<&'a str, TracableInfo>;

// Apply tracable_parser by custom attribute
pub fn expr(s: Span) -> IResult<Span, String> {
    alt((expr_plus, expr_minus, term))(s)

pub fn expr_plus(s: Span) -> IResult<Span, String> {
    let (s, x) = term(s)?;
    let (s, y) = char('+')(s)?;
    let (s, z) = expr(s)?;
    let ret = format!("{}{}{}", x, y, z);
    Ok((s, ret))

pub fn expr_minus(s: Span) -> IResult<Span, String> {
    let (s, x) = term(s)?;
    let (s, y) = char('-')(s)?;
    let (s, z) = expr(s)?;
    let ret = format!("{}{}{}", x, y, z);
    Ok((s, ret))

pub fn term(s: Span) -> IResult<Span, String> {
    let (s, x) = term_internal(s)?;
    Ok((s, x))

pub fn term_internal(s: Span) -> IResult<Span, String> {
    let (s, x) = char('1')(s)?;
    Ok((s, x.to_string()))

fn main() {
    // Configure trace setting
    let info = TracableInfo::new().parser_width(64).fold("term");
    let ret = expr(LocatedSpan::new_extra("1-1+1+1-1", info));

    // Show histogram


Licensed under either of

at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


~37K SLoC