Using Multiple Levels Of "many" In Rust's nom Parser
I kept running into stuff with `many0``, `many1``, and `many_till`` 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 `many1`` in both cases. Adding an `opt`` 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
Code
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
Code
// // 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("")))
// }