tzlaine / parser

A C++ parser combinator library.
Boost Software License 1.0
81 stars 12 forks source link

Describe backtracking #35

Closed akrzemi1 closed 9 months ago

akrzemi1 commented 9 months ago

I only learned from the JSON example that there is a system for backtracking incomparible with Boost.Spirit.

I am trying to port my parser code from Boost.Spirit X3 to Boost.Parser and stumbled upon the problem, how to rewrite the usage of boost::spirit::qi::hold. Boost.Spirit X3 has backtracking disabled by default -- for parsing performance, I guess -- and when defining alternatives one has to exlicitly enable it.

Because the port from Boost.Spirit X3 will be a common use case I would recommend:

tzlaine commented 9 months ago

I'm fine describing backtracking more fully (and I'm going to), but I don't understand the statement that X3 does not have backtracking on by default. Consider the case you reported earlier, slightly modified:

#include <boost/parser/parser.hpp>
#include <vector>

struct X {
  char a;
  int b;
};

struct Y {
  std::vector<X> x;
  int c;
};

int main()
{
  namespace bp = boost::parser;
  auto parse_x = bp::int_ >> bp::int_;
  auto parse_y = +parse_x >> bp::int_;

  Y y;
  auto b = bp::parse("1 3 4", parse_y, bp::ws, y);
}

I changed it so that it parses ints all the time, instead of a char at the beginning of parse_x.

This still works because the second iteration of parse_x, having eaten "1 3" fails to eat two more ints, since it sees only "4" next in the input. parse_y, in which +parse_x is a subparser, must then backtrack a bit, and parse the "4" using the bp::int_ at the end of parse_y. This is how Spriit 1 and 2 worked. Is this different from how X3 works? If so, I can't find that in the X3 docs.

akrzemi1 commented 9 months ago

My apologies. I misremembered the situation. Backtracking works in Boost.Spirit, at least in general. It is the unintuitive behaviour of the alternative parser that requires the use of hold directive. It does not reset attributes from the alternative that didn't ultimately match. I can refer you to the short email thread from 13 years ago:| https://sourceforge.net/p/spirit/mailman/spirit-general/thread/AANLkTimwgyG85kDLKwpd9uwSkaKw%2BwvMcnU97i9dvA%3De%40mail.gmail.com/#msg25929065

akrzemi1 commented 9 months ago

And given that, this PR doesn't make sense. Maybe there is a smaller issue with the alternative, but that would not be this PR.