2017-01-16 48 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]