2017-01-16 44 views
2

我经常需要解析逗号分隔0 or more list助推精神x3。 我知道%-operator,它将1 or more list解析为std::vector。 当我需要一个0 or more list我目前这样做-(element_parser % separator),这是我想要的,但解析为boost::optional<std::vector>,这是不是我所追求的东西。 那么我该如何制作一个解析器,它使用boost spirit x3将一个逗号分隔的0 or more list解析为普通的std :: vector。解析逗号分隔0或更多列表使用助推精神x3

+1

属性是兼容的。尝试一下。如果你问我,兼容性/转换规则是Spirit Library的胜利点。 – sehe

回答

3

也许我失去了一些东西,但使用-按预期工作对我来说:

#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]