Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用Boost.Spirit解析嵌套列表_C++_Boost Spirit - Fatal编程技术网

C++ 使用Boost.Spirit解析嵌套列表

C++ 使用Boost.Spirit解析嵌套列表,c++,boost-spirit,C++,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::dou

我试图用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";
}
我面临的问题是,它不接受空列表。例如,通过如下方式更改字符串:

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

然后我没有匹配项(即
match==false
it==string.begin()
)。显然,向量仍然会被填充,但最后一个空列表丢失了。有人能解释一下为什么会出现这种情况,以及如何解决它吗?

您正在使用Qi域中的原始表达式模板的
auto
——99.9%的情况下是未定义的行为:

现在,在修复该问题的同时,还要使列表正文成为可选的:

#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";
        }
    }
}

%
解析器定义为:“List.Parse a delimited b一次或多次”。IIRC,您可以简单地将列表标记为可选,它将执行您想要的操作:
“[”>>-(listRule%,”>>“]嗯。。不,似乎不起作用。在这种情况下(同时使用
listRule
list2Rule
中的所有组合,我得到了一个向量列表,每个向量只有一个值…谢谢你的回答。但是,这不是我所期望的输出…请看我修改过的问题。该死。下次我应该更加注意输出。显然,这是不对的:)固定的。问题是在这种情况下,属性兼容性的魔力太大了:)是的,效果非常好!因此缺少三点:(a)将
auto
与规则一起使用是未定义的行为,(b)可以将解析器设置为可选的
-
,(c)根据解析器的实际工作方式,每个规则都可以有自己的属性类型。谢谢!
#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