Discussion:
boost::spirit multiline comment parsing - how?
Markus Werle
22 years ago
Permalink
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/



------------------------ Yahoo! Groups Sponsor ---------------------~-->
Get 128 Bit SSL Encryption!
http://us.click.yahoo.com/xaxhjB/hdqFAA/bW3JAA/EbFolB/TM
---------------------------------------------------------------------~->

Info: <http://www.boost.org>
Wiki: <http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl>
Unsubscribe: <mailto:boost-users-***@yahoogroups.com>


Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
Joel de Guzman
22 years ago
Permalink
Post by Markus Werle
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-***@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.
Post by Markus Werle
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.
Post by Markus Werle
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


------------------------ Yahoo! Groups Sponsor ---------------------~-->
Get 128 Bit SSL Encryption!
http://us.click.yahoo.com/xaxhjB/hdqFAA/bW3JAA/EbFolB/TM
---------------------------------------------------------------------~->

Info: <http://www.boost.org>
Wiki: <http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl>
Unsubscribe: <mailto:boost-users-***@yahoogroups.com>


Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
Loading...