On Thu, Feb 22, 2024 at 4:36 PM Christian Mazakas via Boost
wrote:
[snip]
### The Feedback
The differences between Spirit.X3 and Parser need to be made much more
clear by the
documentation, by which I mean:
* Spirit X3 has rules that do not compose well — the attributes produced
by a rule can change depending on the context in which you use the rule.
I will add this to the docs as well, but I thought I'd post here an
example of what I was referring to above. Here is a complete program
using X3:
#include
#include <iostream>
#include <set>
#include <string>
#include <vector>
namespace x3 = boost::spirit::x3;
using ints_type = x3::rule;
BOOST_SPIRIT_DECLARE(ints_type);
x3::rule ints = "ints";
constexpr auto ints_def = x3::int_ % ',';
BOOST_SPIRIT_DEFINE(ints);
#define FIXED_ATTRIBUTE 0
int main()
{
std::string input = "43, 42";
auto first = input.begin();
auto const last = input.end();
#if FIXED_ATTRIBUTE
std::vector<int> result;
#else
std::set<int> result;
#endif
bool success = x3::phrase_parse(first, last, ints, x3::space, result);
if (success) {
// We want this to print "43 42\n".
for (auto x : result) {
std::cout << x << ' ';
}
std::cout << "\n";
}
return 0;
}
IMO, the problem with this is that, even though I specified a vector
as the rule's attribute type, I can feed the rule a set (#define
FIXED_ATTRIBUTE 1), and it happily populates it with the parsed
values. Note that this sorts, and in this case reorders, the values.
I think this looseness is important in many cases, but there's no way
to turn it off in X3. In Parser the way to turn it off is to use a
rule instead of a parser. My inability to disable this looseness
resulted in wrong results in an X3 YAML parser I was working on. I
really loved so much of the design of X3, that my frustration with
this problem was a pretty big part of the motivation for writing
Parser.
Zach