使用提升精神 x3 解析逗号分隔的 0 或多个列表

Parsing a comma separated 0 or more list using boost spirit x3

本文关键字:分隔 列表 x3      更新时间:2023-10-16

我经常需要在boost spirit x3中解析逗号分隔0 or more list。我知道将1 or more list解析为std::vector%-operator.当我需要0 or more list时,我目前是这样-(element_parser % separator)这样做的,它可以做我想做的,但解析成一个boost::optional<std::vector>,这不是我想要的东西。那么我怎样才能制作一个解析器,它使用 boost spirit x3 将逗号分隔0 or more list解析为普通的 std::vector。

也许我错过了一些东西,但使用-对我来说是预期的:

#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
const x3::rule<class number_list_tag, std::vector<int>> integer_list = "integer_list";
const auto integer_list_def = -(x3::int_ % ',');
BOOST_SPIRIT_DEFINE(integer_list);
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec)
{
    bool first = true;
    os << '[';
    for (const T& x : vec)
    {
        if (first)
            first = false;
        else
            os << ", ";
        os << x;
    }
    os << ']';
    return os;
}
std::vector<int> parse(const std::string& src)
{
    std::vector<int> result;
    auto iter = src.begin();
    bool success = x3::phrase_parse(iter, src.end(), integer_list, x3::space, result);
    if (!success || iter != src.end())
        throw std::runtime_error("Failed to parse");
    else
        return result;
}
int main()
{
    std::cout << """:t" << parse("") << std::endl;
    std::cout << ""5":t" << parse("5") << std::endl;
    std::cout << ""1, 2, 3":t" << parse("1, 2, 3") << std::endl;
}

输出为:

"":     []
"5":    [5]
"1, 2, 3":      [1, 2, 3]