Marwes / combine

A parser combinator library for Rust
https://docs.rs/combine/*/combine/
MIT License
1.3k stars 94 forks source link

Successful parser will not clear the error stack #355

Closed yihuaf closed 4 months ago

yihuaf commented 1 year ago

Not sure if this is intended behavior or a bug. The operations such as many will parse success 0 or N times and will stop at the last failed parse. The parse will generate some error. The parsing operation will be successful but the error stack is not cleared. A subsequent skip fails will cause the errors from the failed many the N+1 failed parse to show up.

Consider the following example:

    #[test]
    fn test_skip() {
        use combine::EasyParser;
        let ret = many::<String, _, _>(combine::parser::char::char('a'))
            .skip(combine::parser::char::char('b'))
            .easy_parse("a");
        println!("{:?}", ret);
    }

The input is a "a", and the parser is to parse many 'a' followed by a b (which will fail). The expected error is:

errors: [Unexpected(Static("end of input")), Expected(Token('b'))]

But the actual output is:

errors: [Unexpected(Static("end of input")), Expected(Token('a')), Expected(Token('b'))]

The Expected(Token('a')) error is from the many parser parsing "a". It should be cleared once the many parser is deemed successful.

Marwes commented 1 year ago

That is expected behavior. At the point where it fails another a or a b would be accepted. Arguably we could drop the a expectation here since the full parse would fail but I am not entirely sure how that would be decided without losing other cases where the a expectation should remain in the error.