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

------------------------------------------------------------------------------
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.