Home
Head's Up: I'm in the middle of upgrading my site. Most things are in place, but there are something missing and/or broken including image alt text. Please bear with me while I'm getting things fixed.

Using Multiple Levels Of "many" In Rust's nom Parser

I kept running into stuff with [TODO: Code shorthand span ] , [TODO: Code shorthand span ] , and [TODO: Code shorthand span ] in nom that I thought should have worked. Specifically when I was having one looping over another one by nesting them

I finally broke things out to it's own file and got things working by using [TODO: Code shorthand span ] in both cases. Adding an [TODO: Code shorthand span ] to the first one makes sure that things pass.

Actually this may not always work. I'm still having problems with it and have ended up going to many _ till

rust
use nom::bytes::complete::tag;
use nom::combinator::opt;
use nom::multi::many1;
use nom::IResult;

fn main() {
    dbg!(parse("aaaabbbb")).unwrap();
    dbg!(parse("wwwwxxxx")).unwrap();
    dbg!(parse("xxxxyyyy")).unwrap();
}

fn parse(source: &str) -> IResult<&str, Option<Vec<Vec<&str>>>> {
    let (source, response) = opt(many1(level2))(source)?;
    Ok((source, response))
}
fn level2(source: &str) -> IResult<&str, Vec<&str>> {
    dbg!(&source);
    let (source, response) = many1(tag("x"))(source)?;
    Ok((source, response))
}

Things That Didn't Work

rust
// // this doesn't work either
// fn parse(source: &str) -> IResult<&str, Vec<Vec<&str>>> {
//     let (source, response) = many_till(level2, eof)(source)?;
//     Ok((source, response.0))
// }
// fn level2(source: &str) -> IResult<&str, Vec<&str>> {
//     dbg!(&source);
//     let (source, response) = many0(tag("a"))(source)?;
//     Ok((source, response))
// }

// // these don't work. it throws an error because
// it looks like its sending an empty string to
// many0 on the second time thru
// fn parse(source: &str) -> IResult<&str, Vec<String>> {
//     let (source, response) = many0(level2)(source)?;
//     Ok((source, response))
// }
// fn level2(source: &str) -> IResult<&str, String> {
//     dbg!(&source);
//     let (source, response) = many0(is_not("x"))(source)?;
//     Ok((source, response.join("")))
// }