I don't understand the behaviour of x3 in the following example (taken from a larger grammar).
The grammar is a bit weird, granted, but roughly it implements (lal)?(<char>)?
. When the second group is not present, it defaults to <default>
. I don't understand why on the input "lal<char>"
I get defaultchar
as a result:
#include <iostream>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
int main()
{
namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;
using ascii::alnum;
using ascii::char_;
using ascii::space;
using x3::attr;
using x3::eoi;
using x3::lexeme;
using x3::lit;
using x3::string;
const auto letter
= lit("<") >> string("char") >> lit('>')
| attr(std::string{"default"})
;
const auto letterset
= letter >> eoi
| lit("lal") >> letter >> eoi
;
for (std::string i: {"", "<char>", "lal", "lal<char>"})
{
auto res = std::string{};
auto first = i.cbegin();
auto last = i.cend();
auto r = x3::phrase_parse(first, last, letterset, space, res);
if (r && first == last)
std::cout << i << ": " << res << '\n';
else
std::cout << i << ": failed\n";
}
}
result:
: default
<char>: char
lal: defaultdefault
lal<char>: defaultchar
I do notice that if I swap the alternatives of letterset
, then I get the expected result, which is probably a sign that's related to backtracking: in the original case I get the default
from its first attempt, and the char
from the second one, successful.
I'm very tempted to call this a bug, but I'm an x3 newbie...
This is X3 from Boost 1.65.
Thanks in advance @sehe :)