#ifndef __CONFIGGRAMMAR_H__ #define __CONFIGGRAMMAR_H__ #include #include #include #include using namespace boost::spirit; struct dbg { std::string tag; dbg(const std::string& tag) : tag(tag) {} template void operator()(IteratorT const& first, IteratorT const& last) const { std::cout << tag << ": " << std::string(first, last) << std::endl; } }; struct configreader : public grammar { template struct definition { definition(configreader const& self) { // todo: // add comment parser // -> try this with skip parser // figure out how to get it to parse a multi line file correctly // make it parse both LF and CRLF as lineendings // -> use eol_p // make it parse more whitespace than just single spaces. // -> try this with skip parser S = *blank_p; comment = comment_p("//") | comment_p("#") | comment_p(";") | eol_p ; EOL = S >> comment; word = lexeme_d [ alpha_p >> *(alnum_p | '_') ]; // ptr to array *[64]PROCESS // array of ptrs [64]*PROCESS // ptr *PROCESS // ptr to other proc pServer:*PROCESS // // process specifier can be: // field pointing to either a handle, or a PROCESS struct // or a process name - in quotes // // array count may be either a number, or a fieldname // // typename may be a typename, or '@mapname[fieldname]' number = (str_p("0x") >> +xdigit_p ) ; // doc says: if_p("0x")[hex_p].else_p[uint_p]; arraycount= (str_p("0x") >> +xdigit_p ) | +digit_p | word; typespec= *( ch_p('*') | ('[' >> arraycount >> ']') ) >> word; fielddef= word >> S >> typespec >> EOL; structdef= ch_p('!') >> word >> EOL >> +(fielddef|EOL); struct_section = +(structdef|EOL); memorymap= number >> S >> word >> EOL; memory_section = +(memorymap|EOL); cinfomap= word >> S >> word >> EOL; cinfo_section = +(cinfomap|EOL); // todo: create some kind of mapping of sectionname => section parser section = (ch_p('=') >> "structs" >> EOL >> struct_section) | (ch_p('=') >> "cinfo" >> EOL >> cinfo_section) | (ch_p('=') >> "memory" >> EOL >> memory_section) | EOL; config_file = +(section) >> end_p; #ifdef BOOST_SPIRIT_DEBUG BOOST_SPIRIT_DEBUG_NODE(word ); BOOST_SPIRIT_DEBUG_NODE(number ); BOOST_SPIRIT_DEBUG_NODE(EOL ); BOOST_SPIRIT_DEBUG_NODE(S ); BOOST_SPIRIT_DEBUG_NODE(comment ); BOOST_SPIRIT_DEBUG_NODE(struct_section); BOOST_SPIRIT_DEBUG_NODE(structdef ); BOOST_SPIRIT_DEBUG_NODE(fielddef ); BOOST_SPIRIT_DEBUG_NODE(typespec ); BOOST_SPIRIT_DEBUG_NODE(arraycount ); BOOST_SPIRIT_DEBUG_NODE(cinfomap ); BOOST_SPIRIT_DEBUG_NODE(cinfo_section ); BOOST_SPIRIT_DEBUG_NODE(memorymap ); BOOST_SPIRIT_DEBUG_NODE(memory_section); BOOST_SPIRIT_DEBUG_NODE(section_name ); BOOST_SPIRIT_DEBUG_NODE(section ); BOOST_SPIRIT_DEBUG_NODE(config_file ); #endif } rule S, EOL, comment, number, word, struct_section, structdef, fielddef, typespec, arraycount, cinfomap, cinfo_section, memorymap, memory_section, section_name, section, config_file; rule const& start() const { return config_file; } }; }; #endif