nom icon indicating copy to clipboard operation
nom copied to clipboard

[Question] Nested many* don't work as expected

Open curldivergence opened this issue 2 years ago • 1 comments

  • Rust version : rustc 1.56.0 (09c42c458 2021-10-18)
  • nom version : 7.1
  • nom compilation features used: none

Hi, I'm not sure if it's a bug or I just don't understand the idea behind the many* parsers, but I'd expect this test to pass:

let result: Result<(&str, Vec<Vec<&str>>), nom::Err<Error<&str>>> = many1(many0(tag("ab")))("abab");

// fails with
// left: `Err(Error(Error { input: "", code: Many1 }))`,
// right: `Ok(("", [["ab", "ab"]]))`', src\main.rs:16:5
assert_eq!(result, Ok(("", vec![vec!["ab", "ab"]])));

However it fails with the reasoning given in the comments. Could you help me sort this out, please? :)

Thanks!

curldivergence avatar Nov 17 '21 17:11 curldivergence

According to the document, many0 and many1 will return an error if the parser passed to the combinator accepts empty inputs. So the many0 here parses "abab" into vec!["ab", "ab"] first, then the many1 applies the many0 to the rest inputs, which is "", again. Because many0 accepts "", many1 simply returns an error in order to prevent going into an infinite loop.

I actually just started using nom and got confused about the behavior of many0 and many1 as well. To me, it seems more reasonable that many1 and many0 return the parsed result instead of an error when they encounter accepted empty inputs. It's appreciated if anyone could give some deeper explanation or give a proper solution.

HareInWeed avatar Nov 21 '21 15:11 HareInWeed