Я написал несколько правил для разбора чисел с плавающей запятой на два 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", в вектор verts структуры, а все числа с плавающей запятой, которым предшествует "vn", - в нормы. Это здорово, но я действительно не знаю, почему это работает.
Теперь, если я правильно понимаю, правило, определенное, как показано ниже, помещает все свои результаты в std :: vector float.
qi::rule<std::string::const_iterator, std::vector<float>(), iso8859::space_type> vertex;
Итак, глядя на код синтаксического анализа, показанный выше, и зная, что такое правило, как вершина, разбирается в std :: vector с плавающей запятой, очевидно, такое правило, как vertexList (показанное выше), объединяет результаты из вершины в один std :: vector с плавающей запятой. ? Увидев такое поведение, можно подумать, что можно просто записать эти два правила (vertex и vertexList) как одно, но, к сожалению, это не работает:
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 :: фраза_parse возвращает успешный синтаксический анализ, но std :: vector в структуре больше не заполняется .. Что мне здесь не хватает?
vertex
генерирует std :: vector ‹float› (), ноcomment
нарушает это. Другими словами, у вас не может быть в одном правиле альтернативных синтаксических анализаторов, которые генерируют другой вывод. - person G. Civardi   schedule 11.07.2013qi::unused_type
(без атрибута), поэтому это не имеет значения :) - person sehe   schedule 11.07.2013