Reputation: 5088
I often need to parse a comma separated 0 or more list
in boost spirit x3.
I know the %-operator
which parses a 1 or more list
into an std::vector
.
When I need a 0 or more list
I currently do it like this -(element_parser % separator)
, which does what I want, but parses into a boost::optional<std::vector>
, which is not quite the thing I am after.
So how can I make a parser, which parses a comma separated 0 or more list
into a plain std::vector using boost spirit x3.
Upvotes: 3
Views: 815
Reputation: 27633
Perhaps I'm missing something, but using -
works as expected for me:
#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;
}
Output is:
"": []
"5": [5]
"1, 2, 3": [1, 2, 3]
Upvotes: 4