EDIT I misread the question. Here's the rewrite:
Live On Coliru
Live On Coliru (with debug output)
struct V2 { float a, b; } ;
struct V3 { float a, b, c; } ;
struct VertexProperty {
std::vector<V3> vertices, normals;
std::vector<V2> texCoords;
};
BOOST_FUSION_ADAPT_STRUCT(V2, a,b)
BOOST_FUSION_ADAPT_STRUCT(V3, a,b,c)
BOOST_FUSION_ADAPT_STRUCT(VertexProperty, vertices,normals,texCoords)
template <typename Iterator>
struct Parser : qi::grammar<Iterator, VertexProperty()> {
Parser() : Parser::base_type(start) {
v2 = qi::double_ >> qi::double_;
v3 = qi::double_ >> qi::double_ >> qi::double_;
vertexproperty = qi::lit("VertexProperty")
>> '{'
>> "vertex" >> '[' >> (v3 % ',') >> ']'
>> "normal" >> '[' >> (v3 % ',') >> ']'
>> "texCoord" >> '[' >> (v2 % ',') >> ']'
>> '}';
start = qi::skip(qi::space) [vertexproperty];
BOOST_SPIRIT_DEBUG_NODES((v2)(v3)(vertexproperty))
}
private:
qi::rule<Iterator, VertexProperty()> start;
qi::rule<Iterator, VertexProperty(), qi::space_type> vertexproperty;
qi::rule<Iterator, V2(), qi::space_type> v2;
qi::rule<Iterator, V3(), qi::space_type> v3;
};
Notes:
- use a typed element instead of 'just' a vector
- use a separate rule for the V3
- use literals (
qi::lit
) instead of qi::char_
because you do not want to expose the matched interpunction
- use the list operator (
a % b
matches a [b a]...
already)
UPDATE: Full Live Demo
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct.hpp>
namespace qi = boost::spirit::qi;
struct V2 { float a, b; } ;
struct V3 { float a, b, c; } ;
struct VertexProperty {
std::vector<V3> vertices, normals;
std::vector<V2> texCoords;
};
BOOST_FUSION_ADAPT_STRUCT(V2, a,b)
BOOST_FUSION_ADAPT_STRUCT(V3, a,b,c)
BOOST_FUSION_ADAPT_STRUCT(VertexProperty, vertices,normals,texCoords)
template <typename Iterator>
struct Parser : qi::grammar<Iterator, VertexProperty()> {
Parser() : Parser::base_type(start) {
v2 = qi::double_ >> qi::double_;
v3 = qi::double_ >> qi::double_ >> qi::double_;
vertexproperty = qi::lit("VertexProperty")
>> '{'
>> "vertex" >> '[' >> (v3 % ',') >> ']'
>> "normal" >> '[' >> (v3 % ',') >> ']'
>> "texCoord" >> '[' >> (v2 % ',') >> ']'
>> '}';
start = qi::skip(qi::space) [vertexproperty];
BOOST_SPIRIT_DEBUG_NODES((v2)(v3)(vertexproperty))
}
private:
qi::rule<Iterator, VertexProperty()> start;
qi::rule<Iterator, VertexProperty(), qi::space_type> vertexproperty;
qi::rule<Iterator, V2(), qi::space_type> v2;
qi::rule<Iterator, V3(), qi::space_type> v3;
};
int main() {
using Iterator = std::string::const_iterator;
std::string const sample = "VertexProperty {\n"
" vertex [ 0.0 0.0 1.0,\n"
" 1.0 1.0 1.0,\n"
" 1.0 0.0 1.0]\n"
" normal [1.0 0.0 0.0,\n"
" 0.0 1.0 0.0,\n"
" 0.0 0.0 1.0]\n"
" texCoord [0.0 0.0,\n"
" 1.0 0.0,\n"
" 1.0 1.0]\n"
"}";
auto f = sample.begin(), l = sample.end();
VertexProperty data;
bool ok = qi::parse(f, l, Parser<Iterator>(), data);
if (ok) {
std::cout << "Parsed: " << data.vertices.size() << ", " << data.normals.size() << ", " << data.texCoords.size() << "\n";
} else {
std::cout << "Parse failed\n";
}
if (f!=l)
std::cout << "Remaining input: '" << std::string(f,l) << "'\n";
}
Prints
Parsed: 3, 3, 3
With debug info
<vertexproperty>
<try>VertexProperty {\n ve</try>
<v3>
<try> 0.0 0.0 1.0,\n 1</try>
<success>,\n 1.0 1.0 1.0,\n</success>
<attributes>[[0, 0, 1]]</attributes>
</v3>
<v3>
<try>\n 1.0 1.0 1.0,\n </try>
<success>,\n 1.0 0.0 1.0]\n</success>
<attributes>[[1, 1, 1]]</attributes>
</v3>
<v3>
<try>\n 1.0 0.0 1.0]\n </try>
<success>]\n normal [1.0 0.0 0</success>
<attributes>[[1, 0, 1]]</attributes>
</v3>
<v3>
<try>1.0 0.0 0.0,\n 0.</try>
<success>,\n 0.0 1.0 0.0,\n</success>
<attributes>[[1, 0, 0]]</attributes>
</v3>
<v3>
<try>\n 0.0 1.0 0.0,\n </try>
<success>,\n 0.0 0.0 1.0]\n</success>
<attributes>[[0, 1, 0]]</attributes>
</v3>
<v3>
<try>\n 0.0 0.0 1.0]\n </try>
<success>]\n texCoord [0.0 0.0</success>
<attributes>[[0, 0, 1]]</attributes>
</v3>
<v2>
<try>0.0 0.0,\n 1.0 0.</try>
<success>,\n 1.0 0.0,\n </success>
<attributes>[[0, 0]]</attributes>
</v2>
<v2>
<try>\n 1.0 0.0,\n </try>
<success>,\n 1.0 1.0]\n}</success>
<attributes>[[1, 0]]</attributes>
</v2>
<v2>
<try>\n 1.0 1.0]\n}</try>
<success>]\n}</success>
<attributes>[[1, 1]]</attributes>
</v2>
<success></success>
<attributes>[[[[0, 0, 1], [1, 1, 1], [1, 0, 1]], [[1, 0, 0], [0, 1, 0], [0, 0, 1]], [[0, 0], [1, 0], [1, 1]]]]</attributes>
</vertexproperty>