Понимание оператора списка (%) в Boost.Spirit
Можете ли вы помочь мне понять разницу междуa % b
парсер и его расширенa >> *(b >> a)
форма в Boost.Spirit? Даже еслисправочник утверждает, что они эквивалентны,
Оператор списка,a % b
, является двоичным оператором, который соответствует списку из одного или нескольких повторенийa
разделены вхождениямиb
, Это эквивалентноa >> *(b >> a)
.
следующая программа дает разные результаты в зависимости от того, какой из них используется:
#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
struct Record {
int id;
std::vector<int> values;
};
BOOST_FUSION_ADAPT_STRUCT(Record,
(int, id)
(std::vector<int>, values)
)
int main() {
namespace qi = boost::spirit::qi;
const auto str = std::string{"1: 2, 3, 4"};
const auto rule1 = qi::int_ >> ':' >> (qi::int_ % ',') >> qi::eoi;
const auto rule2 = qi::int_ >> ':' >> (qi::int_ >> *(',' >> qi::int_)) >> qi::eoi;
Record record1;
if (qi::phrase_parse(str.begin(), str.end(), rule1, qi::space, record1)) {
std::cout << record1.id << ": ";
for (const auto& value : record1.values) { std::cout << value << ", "; }
std::cout << '\n';
} else {
std::cerr << "syntax error\n";
}
Record record2;
if (qi::phrase_parse(str.begin(), str.end(), rule2, qi::space, record2)) {
std::cout << record2.id << ": ";
for (const auto& value : record2.values) { std::cout << value << ", "; }
std::cout << '\n';
} else {
std::cerr << "syntax error\n";
}
}
1: 2, 3, 4,
1: 2,
rule1
а такжеrule2
отличаются только тем, чтоrule1
использует оператор списка ((qi::int_ % ',')
) а такжеrule2
использует его расширенную форму ((qi::int_ >> *(',' >> qi::int_))
). Тем не мение,rule1
произведенный1: 2, 3, 4,
(как и ожидалось) иrule2
произведенный1: 2,
, Я не могу понять результатrule2
: 1) почему он отличается отrule1
и 2) почему были3
а также4
не входит вrecord2.values
даже еслиphrase_parse
вернули как-нибудь?