Теперь давайте добавим отладочный вывод и тело теста:
Live On Wandbox
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <iostream>
#include <iomanip>
using label_t = std::vector<std::tuple<std::string, int>>;
namespace std {
std::ostream& operator<<(std::ostream& os, label_t::value_type const& t) {
auto const& [k,v] = t;
return os << "[" << std::quoted(k) << "," << v << "]";
}
std::ostream& operator<<(std::ostream& os, label_t const& m) {
os << "{";
for (auto&& el:m) os << el << ",";
return os << "}";
}
}
struct BulkDataParams {
std::string strUUID;
int16_t subcam;
int64_t pts_beg;
int64_t pts_len;
int64_t pts_gap;
label_t labels;
};
BOOST_FUSION_ADAPT_STRUCT(BulkDataParams, strUUID, subcam, pts_beg, pts_len, pts_gap, labels)
template <typename Iterator> struct load_parser : boost::spirit::qi::grammar<Iterator, BulkDataParams()> {
load_parser() : load_parser::base_type(start) {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
uuid = '"' >> qi::raw [
hex_<4>{} >> qi::repeat(3)['-' >> hex_<2>{}] >> '-' >> hex_<6>{}
] >> '"';
quoted_string = '"' >> *~qi::char_('"') >> '"';
label = '{' >> quoted_string >> ',' >> qi::int_ >> '}';
start = qi::skip(ascii::space) [ '{'
>> uuid >> ','
>> qi::auto_ >> ','
>> qi::auto_ >> ','
>> qi::auto_ >> ','
>> qi::auto_ >> ','
>> '{' >> -(label % ',') >> '}'
>> '}' >> ';'
];
BOOST_SPIRIT_DEBUG_NODES(
(uuid) (quoted_string) (label) (start)
)
}
template<int N> using hex_ = boost::spirit::qi::int_parser<std::intmax_t, 16, 2*N, 2*N>;
private:
boost::spirit::qi::rule<Iterator, std::string()> uuid;
boost::spirit::qi::rule<Iterator, std::string()> quoted_string;
boost::spirit::qi::rule<Iterator, label_t::value_type(), boost::spirit::ascii::space_type> label;
boost::spirit::qi::rule<Iterator, BulkDataParams()> start;
};
int main() {
for (std::string const input : {
R"({ "68965363-2d87-46d4-b05d-f293f2c8403b", 0, 1583798400000000, 86400000000, 600000000, { { "motorbike", 5 }, { "aeroplane", 6 } } };)",
})
{
auto f = begin(input), l = end(input);
BulkDataParams bdp;
load_parser<std::string::const_iterator> p;
if (parse(f, l, p, bdp)) {
std::cout << "Parsed: " << boost::fusion::as_vector(bdp) << "\n";
} else {
std::cout << "Parse Failed\n";
}
if (f != l) {
std::cout << "Remaining unparsed: " << std::quoted(std::string(f,l)) << "\n";
}
}
}
Обычный вывод:
Parsed: (68965363-2d87-46d4-b05d-f293f2c8403b 0 1583798400000000 86400000000 600000000 {["motorbike",5],["aeroplane",6],})
Отладочный вывод:
<start>
<try>{ "68965363-2d87-46d</try>
<uuid>
<try>"68965363-2d87-46d4-</try>
<success>, 0, 158379840000000</success>
<attributes>[[6, 8, 9, 6, 5, 3, 6, 3, -, 2, d, 8, 7, -, 4, 6, d, 4, -, b, 0, 5, d, -, f, 2, 9, 3, f, 2, c, 8, 4, 0, 3, b]]</attributes>
</uuid>
<label>
<try> { "motorbike", 5 },</try>
<quoted_string>
<try>"motorbike", 5 }, { </try>
<success>, 5 }, { "aeroplane"</success>
<attributes>[[m, o, t, o, r, b, i, k, e]]</attributes>
</quoted_string>
<success>, { "aeroplane", 6 }</success>
<attributes>[[[m, o, t, o, r, b, i, k, e], 5]]</attributes>
</label>
<label>
<try> { "aeroplane", 6 } </try>
<quoted_string>
<try>"aeroplane", 6 } } }</try>
<success>, 6 } } };</success>
<attributes>[[a, e, r, o, p, l, a, n, e]]</attributes>
</quoted_string>
<success> } };</success>
<attributes>[[[a, e, r, o, p, l, a, n, e], 6]]</attributes>
</label>
<success></success>
<attributes>[[[6, 8, 9, 6, 5, 3, 6, 3, -, 2, d, 8, 7, -, 4, 6, d, 4, -, b, 0, 5, d, -, f, 2, 9, 3, f, 2, c, 8, 4, 0, 3, b], 0, 1583798400000000, 86400000000, 600000000, [[[m, o, t, o, r, b, i, k, e], 5], [[a, e, r, o, p, l, a, n, e], 6]]]]</attributes>
</start>