2017-08-23 45 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