我编写了一些规则来将浮点数解析为两个 std::vector 的浮点数,它们又存储在一个结构中:
数据输入:
#
# object name01
#
v -1.5701 33.8087 0.3592
v -24.0119 0.0050 21.7439
# a comment
vn 0.0000 0.5346 0.8451
vn 0.8331 0.5531 -0.0000
# another comment
结构:
struct ObjParseData
{
ObjParseData() : verts(), norms() {}
std::vector<float> verts;
std::vector<float> norms;
};
以及相关的解析代码:
struct objGram : qi::grammar<std::string::const_iterator, ObjParseData(), iso8859::space_type>
{
objGram() : objGram::base_type(start)
{
vertex = 'v' >> qi::double_ >> qi::double_ >> qi::double_;
normal = "vn" >> qi::double_ >> qi::double_ >> qi::double_;
comment = '#' >> qi::skip(qi::blank)[ *(qi::print) ];
vertexList = *(vertex | comment);
normalList = *(normal | comment);
start = vertexList >> normalList;
}
qi::rule<std::string::const_iterator, ObjParseData(), iso8859::space_type> start;
qi::rule<std::string::const_iterator, std::vector<float>(), iso8859::space_type> vertexList;
qi::rule<std::string::const_iterator, std::vector<float>(), iso8859::space_type> normalList;
qi::rule<std::string::const_iterator, std::vector<float>(), iso8859::space_type> vertex;
qi::rule<std::string::const_iterator, std::vector<float>(), iso8859::space_type> normal;
qi::rule<std::string::const_iterator, iso8859::space_type> comment;
} objGrammar;
ObjParseData resultData;
std::string::const_iterator f = data.cbegin();
bool res = qi::phrase_parse( f, data.cend(), objGrammar, iso8859::space, resultData );
这有效。它将所有以“v”开头的浮点数解析为结构的顶点向量,并将所有以“vn”开头的浮点数解析为范数。这很棒,但我真的不知道为什么会这样。
现在,如果我正确理解这一点,如下定义的规则会将其所有结果放入浮点数的 std::vector 中。
qi::rule<std::string::const_iterator, std::vector<float>(), iso8859::space_type> vertex;
因此,查看上面显示的解析代码并知道像 vertex 这样的规则会解析为 float 的 std::vector,显然像 vertexList (如上所示)这样的规则将来自 vertex 的结果连接到一个 std::vector 的 float ? 所以看到这种行为,你会认为你可以把这两个规则(顶点和顶点列表)写成一个,但不幸的是这不起作用:
vertex = *('v' >> qi::double_ >> qi::double_ >> qi::double_) | comment;
normal = *("vn" >> qi::double_ >> qi::double_ >> qi::double_) | comment;
comment = '#' >> qi::skip(qi::blank)[ *(qi::print) ];
start = vertex >> normal;
代码确实编译并且 qi::phrase_parse 确实返回了一个成功的解析,但是结构中的 std::vector 不再填充了。我在这里缺少什么?