c++ - Boost Spirit Qi, I have a parser that I would like to map onto a struct "dynamically" (meaning order of parameters is not fixed) -


so i'm trying hard boost::spirit::qi under skin. toy example far parser parses wavefront obj material libraries have following format:

newmtl shortbox ka  0.6 0.6 0.6 kd  0.5 0.5 0.5 ks  0 0 0 d  1 ns  0 illum 2 

however ordering of arguments material shortbox can vary. i've created following grammar parses it:

template <typename iterator> struct mtllib_grammar : qi::grammar<iterator, qi::blank_type> {      mtllib_grammar() : mtllib_grammar::base_type(mtl)     {         using qi::char_;         using qi::double_;         using qi::int_;           mtl =             (             ("newmtl" >> +(char_ - qi::eol)  >> qi::eol >> *(mtl_details) >> *(mtl))             | ("#" >> *(qi::char_ - qi::eol) >> qi::eol >> *(mtl))             );          mtl_details =             (             ("ka" >> double_ >> double_ >> double_ >> qi::eol >> *(mtl_details))             | ("kd" >> double_ >> double_ >> double_ >> qi::eol >> *(mtl_details))             | ("ks" >> double_ >> double_ >> double_ >> qi::eol >> *(mtl_details))             | ("d" >> int_ >> qi::eol >> *(mtl_details))             | ("ns" >> int_ >> qi::eol >> *(mtl_details))             | ("illum" >> int_ >> qi::eol >> *(mtl_details))             );     }     qi::rule<iterator, qi::blank_type> mtl;     qi::rule<iterator, qi::blank_type> mtl_details; }; 

now build std::map<std::string,material> material defined as:

struct material {     material()     {         ns = 0.0f;         ke = glm::vec3(0.0f);         kd = glm::vec3(0.0f);         ks = glm::vec3(0.0f);         ka = glm::vec3(0.0f);     }     ~material() {}     glm::vec3 ka;     glm::vec3 kd;     glm::vec3 ks;     glm::vec3 ke;     float ns; }; 

with following fusion adaptations:

boost_fusion_adapt_struct(     glm::vec3,     (float, x)     (float, y)     (float, z)     )  boost_fusion_adapt_struct(     material,     (glm::vec3, ka)     (glm::vec3, kd)     (glm::vec3, ks)     (glm::vec3, ke)     (float, ns)     ) 

so current idea change rule mtl_detailssuch returns complete material , rule mtl returning map of said material key being string after newmtl. however, i'm lost @ how use attributes build material object parse tree, mapping hits of ka, kd, ks ect. onto same struct. reading examples seem either implicitly mapped onto whatever variable associated it, or map simple values, not objects.

thanks cv_and_he found solution. first parameters can occur in file should mapped using boost_fusion_adapt_struct, don't map material::ke since cannot occur naturally in file format.

boost_fusion_adapt_struct(     material,     (glm::vec3, ka)     (glm::vec3, kd)     (glm::vec3, ks)     (float, ns)     ) 

next, grammer ended following:

template <typename iterator> struct mtllib_grammar : qi::grammar<iterator, std::map<std::string, material>(), qi::blank_type> {      mtllib_grammar() : mtllib_grammar::base_type(mtl)     {         using qi::char_;         using qi::float_;         using qi::int_;         using qi::omit;           mtl =             (             *(("newmtl" >> string_rule >> qi::eol >> mtl_details) |             ("#" >> omit[*(qi::char_ - qi::eol)] >> qi::eol ))             );          mtl_details =             (             ("ka" >> glm_rule >> qi::eol) ^             ("kd" >> glm_rule >> qi::eol) ^             ("ks" >> glm_rule >> qi::eol) ^             ("d" >> omit[int_] >> qi::eol) ^             ("ns" >> int_ >> qi::eol) ^             ("illum" >> omit[int_] >> qi::eol)             );          string_rule = +(char_ - qi::eol);         glm_rule = float_ >> float_ >> float_;     }     qi::rule<iterator, std::map<std::string, material>(), qi::blank_type> mtl;      qi::rule<iterator, material(), qi::blank_type> mtl_details;      qi::rule<iterator, std::string(), qi::blank_type> string_rule;     qi::rule<iterator, glm::vec3(), qi::blank_type> glm_rule; }; 

with omit around unused parameters plus comments. otherwise compiler borks being unable map onto types given in rules.


Comments

Popular posts from this blog

authentication - Mongodb revoke acccess to connect test database -

r - Update two sets of radiobuttons reactively - shiny -

ios - Realm over CoreData should I use NSFetchedResultController or a Dictionary? -