2017-08-23 60 views
1

我想用Boost.Spirit來解析嵌套列表的數字。這是我到目前爲止有:用Boost.Spirit解析嵌套列表

//define a test string 
std::string string = "[[\t1 , 2 ], [3, 4, 65.4]]"; 
auto it = string.begin(); 

//parse the string 
std::vector<std::vector<double>> vector; 
auto listRule = "[" >> (qi::double_ % ",") >> "]"; 
auto list2Rule = "[" >> (listRule % ",") >> "]"; 
bool match = qi::phrase_parse(it, string.end(), list2Rule, ascii::space, vector); 

//check if we have a match 
std::cout << "matched: " << std::boolalpha << match << '\n'; 
if (it != string.end()) 
    std::cout << "unmatched part: " << std::string{it, string.end()} << '\n'; 

//print the result 
std::cout << "result\n"; 
for (const auto& v : vector) { 
    std::cout << "["; 
    for (double i : v) 
     std::cout << i << ","; 
    std::cout << "]\n"; 
} 

以上奇妙的作品和版畫:

matched: true 
result 
[1,2,] 
[3,4,65.4,] 

我現在面臨的問題是,它不接受名單。例如,通過改變字符串像這樣:

std::string string = "[[\t1 , 2 ], [3, 4, 65.4], []]"; 

然後我不匹配(即match == falseit == string.begin())。顯然,該矢量仍然被填充,但最後一個空列表丟失。任何人都可以提供解釋,爲什麼這是這種情況,以及如何解決它?

+1

的''%解析器被定義爲:「列表。解析一個或多個分隔符b「。IIRC,你可以簡單地將列表標記爲可選項,並且它會做你想做的事情:'」[「>> - (listRule%」,「)>>」]「; ' – Frank

+0

Uhmm .. nope,似乎不起作用。在這種情況下(和'listRule'和'list2Rule'中的所有組合一起,我得到一個載體列表,每個載體只有一個值... – matpen

回答

1

您使用auto在齊域名原表達模板 - 這是不確定的行爲的99.9%的時間:

現在,當你解決這個問題,也使表體可選:

Live On Coliru

#include <boost/spirit/include/qi.hpp> 
namespace qi = boost::spirit::qi; 

int main() { 
    using It  = std::string::const_iterator; 
    using Skipper = qi::space_type; 

    for(std::string const input : { "[[\t1 , 2 ], [3, 4, 65.4]]", "[[\t1 , 2 ], [3, 4, 65.4], []]", "[]" }) 
    { 
     std::cout << " ---- '" << input << "' ----\n"; 
     auto it = input.begin(); 

     //parse the string 
     using doubles = std::vector<double>; 
     using vectors = std::vector<doubles>; 

     qi::rule<It, doubles(), Skipper> doubles_ = "[" >> -(qi::double_ % ",") >> "]"; 
     qi::rule<It, vectors(), Skipper> vectors_ = "[" >> -(doubles_ % ",") >> "]"; 

     vectors data; 
     bool match = qi::phrase_parse(it, input.end(), vectors_, qi::space, data); 

     //check if we have a match 
     std::cout << "matched: " << std::boolalpha << match << '\n'; 
     if (it != input.end()) 
      std::cout << "unmatched part: " << std::string{it, input.end()} << '\n'; 

     //print the result 
     std::cout << "result\n"; 
     for (const auto& v : data) { 
      std::cout << "["; 
      for (double i : v) 
       std::cout << i << ","; 
      std::cout << "]\n"; 
     } 
    } 
} 

打印

---- '[[ 1 , 2 ], [3, 4, 65.4]]' ---- 
matched: true 
result 
[1,2,] 
[3,4,65.4,] 
---- '[[ 1 , 2 ], [3, 4, 65.4], []]' ---- 
matched: true 
result 
[1,2,] 
[3,4,65.4,] 
[] 
---- '[]' ---- 
matched: true 
result 
+0

謝謝你的但是,這不是我期望的輸出......看到我修改後的問題 – matpen

+0

該死的,下一次我應該多加註意輸出,顯然這是不對的:) – sehe

+0

已修復,問題太多了對於這種情況,屬性兼容性魔術:) – sehe