boost::spirit multiline comment parsing - how?
Hi! While playing around with the examples of the spirit library I feel like I missed some essential points. The far goal I have is to parse a file containing C/C++ comments and assignments of the form name = value; where I drop the comments and store the assignments in a map<string, string>. If You have done something similar, please share Your knowledge with the rest of us. Below is a modifed version of comments.cpp. Here I only try to output any comment found while dropping the other stuff. Why does the parser drop stuff after the 1st assignment? the output of the code is Parsed C-comment successfully! Matched (27) characters: "//test2 /* test1 */// test Any help appreciated. Also I would like not to gather all commenst in one string ... -------- #include "boost/spirit.hpp" #include <iterator> #include <string> #include <iostream> #include <cassert> #include <fstream> #include <map> #include <cassert> /////////////////////////////////////////////////////////////////////////////// // actor called after successfully matching a single character class actor_string { public: actor_string(std::string &rstr) : matched(rstr) { } void operator() (const char *pbegin, const char *pend) const { matched += std::string(pbegin, pend-pbegin); } private: std::string &matched; }; /////////////////////////////////////////////////////////////////////////////// // actor called after successfully matching a C++-comment void actor_cpp (const char *pfirst, const char *plast) { std::cerr << "Parsing C++-comment" << std::endl; std::cerr << "Matched (" << plast-pfirst << ") characters: "; char cbbuffer[128]; strncpy(cbbuffer, pfirst, plast-pfirst); cbbuffer[plast-pfirst] = '\0'; std::cerr << "\"" << cbbuffer << "\"" << std::endl; } /////////////////////////////////////////////////////////////////////////////// // main entry point int main () { using namespace boost::spirit; ///////////////////////////////////////////////////////////////////////////// char const* pCComment = "//test2\n/* test1 */\n\n// test\nalpha = 3.0;\n\n// beta is soo important\nbeta=5.6;\n\n/* \n\nSometimes comments are\ngood since\nbeta = 4.5;\nis a good choice, too\n\n*/"; typedef skipper_iteration_policy<> iter_policy_t; typedef scanner_policies<iter_policy_t> scanner_policies_t; typedef scanner<char const*, scanner_policies_t> phrase_scanner_t; rule<phrase_scanner_t> cpp_comment, ignored, all; cpp_comment = comment_p("/*", "*/") // rule for C-comments | comment_p("//") // rule for C++ comments ; std::string comment_c; all = ( *cpp_comment[actor_string(comment_c)] | *anychar_p ) ; ignored = (space_p | chlit<char>('\n')); parse_info<> result; result = parse (pCComment, all, space_p); if (result.hit) { std::cerr << "Parsed C-comment successfully!" << std::endl; std::cerr << "Matched (" << comment_c.size() << ") characters: "; std::cerr << "\"" << comment_c << "\"" << std::endl; } else { std::cerr << "Failed to parse C/C++-comment!" << std::endl; } std::cerr << std::endl; } Markus -- Compile time analytic differentiation? Yes, at http://daixtrose.sourceforge.net/
Markus Werle wrote:
Hi!
While playing around with the examples of the spirit library I feel like I missed some essential points.
Hi Markus, First of all, FYI, Spirit has its own mailing list: Spirit-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spirit-general I'm regularly reading this mailing list but I would want to request that further discussion happen there so that other Spirit users may see your post.
std::string comment_c;
all = ( *cpp_comment[actor_string(comment_c)] | *anychar_p ) ;
Try: all = *(cpp_comment[actor_string(comment_c)] |anychar_p) ; Notice the Star. Also, anychar_p should probably be replaced by your assignment rule.
result = parse (pCComment, all, space_p);
I think it is better to work on the character level rather than the phrase level. I suggest taking out the skip parser "space_p". HTH, -- Joel de Guzman joel at boost-consulting.com http://www.boost-consulting.com http://spirit.sf.net
participants (2)
-
Joel de Guzman
-
Markus Werle