Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
784 views
in Technique[技术] by (71.8m points)

c++ - Boost Spirit X3: skip parser that would do nothing

I'm getting myself familiarized with boost spirit v3. The question I want to ask is how to state the fact that you don't want to use skip parser in any way.

Consider a simple example of parsing comma-separated sequence of integers:

#include <iostream>
#include <string>
#include <vector>

#include <boost/spirit/home/x3.hpp>

int main()
{
    using namespace boost::spirit::x3;

    const std::string input{"2,4,5"};

    const auto parser = int_ % ',';
    std::vector<int> numbers;

    auto start = input.cbegin();
    auto r = phrase_parse(start, input.end(), parser, space, numbers);

    if(r && start == input.cend())
    {
        // success
        for(const auto &item: numbers)
            std::cout << item << std::endl;
        return 0;
    }

    std::cerr << "Input was not parsed successfully" << std::endl;
    return 1;
}

This works totally fine. However, I would like to forbid having spaces in between (i.e. "2, 4,5" should not be parsed well).

I tried using eps as a skip parser in phrase_parse, but as you can guess, the program ended up in the infinite loop because eps matches to an empty string.

Solution I found is to use no_skip directive (https://www.boost.org/doc/libs/1_75_0/libs/spirit/doc/html/spirit/qi/reference/directive/no_skip.html). So the parser now becomes:

const auto parser = no_skip[int_ % ','];

This works fine, but I don't find it to be an elegant solution (especially providing "space" parser in phrase_parse when I want no whitespace skips). Are there no skip parsers that would simply do nothing? Am I missing something?

Thanks for Your time. Looking forward to any replies.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can use either no_skip[] or lexeme[]. They're almost identical, except for pre-skip (Boost Spirit lexeme vs no_skip).

Are there no skip parsers that would simply do nothing? Am I missing something?

A wild guess, but you might be missing the parse API that doesn't accept a skipper in the first place

Live On Coliru

#include <iostream>
#include <iomanip>
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;

int main() {
    std::string const input{ "2,4,5" };
    auto f = begin(input), l = end(input);

    const auto parser = x3::int_ % ',';
    std::vector<int> numbers;

    auto r = parse(f, l, parser, numbers);

    if (r) {
        // success
        for (const auto& item : numbers)
            std::cout << item << std::endl;
    } else {
        std::cerr << "Input was not parsed successfully" << std::endl;
        return 1;
    }

    if (f!=l) {
        std::cout << "Remaining input " << std::quoted(std::string(f,l)) << "
";
        return 2;
    }
}

Prints

2
4
5

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...