foonathan / lexy

C++ parsing DSL
https://lexy.foonathan.net
Boost Software License 1.0
1.01k stars 67 forks source link

Assertion failure on scan rule failure #135

Closed rkaminsk closed 1 year ago

rkaminsk commented 1 year ago

I was experimenting with scanners and noticed some strange behavior indicated below.

  1. The first variant (as indicated in the comments) works as expected. It produces an error message and the parse result does not have a value.
  2. The second variant produces an error message. However, the parse result has a value.
  3. The third variant leads to an assertion. It seems like the lexy::error_context class does not have the right position.
struct A {
    static constexpr auto rule = dsl::lit_c<'a'>;
    static constexpr auto value = lexy::construct<void>;
};

struct B {
    static constexpr auto rule = dsl::eof;
    static constexpr auto value = lexy::construct<void>;
};

auto input = lexy::zstring_input("b");  
auto scanner = lexy::scan(input, lexy_ext::report_error);  
// variant 1: succeeds
// REQUIRE(!scanner.parse<A>().has_value()));
// variant 2: fails
// REQUIRE(!scanner.parse<B>().has_value()));
// variant 3: causes an assertion
scanner.parse(LEXY_LIT("a"));
lexy/_detail/iterator.hpp:97: constexpr Iterator lexy::_detail::min_range_end(Iterator, Iterator, Iterator)
    [with Iterator = const char*]: Assertion `begin <= end_a && begin <= end_b' failed.
foonathan commented 1 year ago

The second variant produces an error message. However, the parse result has a value.

Yes, this is due to error recovery - when dsl::eof fails, it automatically recovers and continues parsing. If you want to know whether scanning issued any diagnostics, call .finish() and inspect the lexy::validate_result.

The third variant leads to an assertion. It seems like the lexy::error_context class does not have the right position.

That's a bug, I'll investigate.

foonathan commented 1 year ago

Fixed.