Re: Dynamic loop counter on x3
Takatoshi Kondo <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <CA+SaqLGPC45pT0TNg2MhLJuFS+BPu5cYnKeGkTn5ej=iaG6L4w@mail.gmail.com> |
Hi,
I wrote the code based on Seth's approach. I want to separate the
container that contains the result of parsing from repeat counting.
Because I don't always need 5th parameter for outputs result on
`phrase_parse()`.
And capturing variables is acceptable in my usecase. So my code is as follows:
http://melpon.org/wandbox/permlink/aWi42xXerFNjjNsu
#include <string>
#include <iostream>
#include <iomanip>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
int main() {
for (std::string const input :
{
"3 1 2 3", // correct
"4 1 2 3", // too few
"2 1 2 3", // too many
//
" 3 1 2 3 ",
}) {
std::cout << "Parsing " << std::left << std::setw(20) << ("'"
+ input + "':");
using namespace boost::spirit::x3;
struct index_size {
std::size_t index = 0;
std::size_t size = 0;
};
index_size index_size;
auto more = [&index_size](auto &ctx) { _pass(ctx) =
index_size.index++ < index_size.size; };
auto done = [&index_size](auto &ctx) { _pass(ctx) =
index_size.index == index_size.size + 1; };
auto number = [&index_size](auto &ctx) {
index_size.size = _attr(ctx);
};
std::vector<int> v;
auto r =
omit[uint_[number] ]
>> *(eps[more] >> int_)
>> eps[done];
auto it = input.cbegin();
auto end = input.cend();
if (phrase_parse(it, end, r, space, v)) {
std::copy(
v.begin(),
v.end(),
std::ostream_iterator<int>(
std::cout << v.size() << " elements: ", " "
)
);
if (std::size_t rest = std::distance(it, end)) {
std::cout << "(" << rest << " bytes remaining.)";
}
}
else {
std::cout << "Parse failed";
}
std::cout << std::endl;
}
}
Thanks,
Takatoshi Kondo
------------------------------------------------------------------------------