[Spirit 2.1] strange problem with skipper

View: New views
3 Messages — Rating Filter:   Alert me  

[Spirit 2.1] strange problem with skipper

by Christoph Duelli :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Dear all,

(See attachment for a (not) compilable exmaple illustrating the problem.
I am using g++ 4.2.1)

I have a simple rule

  id            %= raw[lexeme[ alpha >> +(alnum | '_' | '.') ]];
  connectstring %= raw[lexeme[id >> '/' >> id >> '@' >> id]];
  start          = connectstring;

which should parse stuff like "mike/test@host".

This does compile and work - as long as I do NOT use a custom white space
skipper.
When I pass my whitespace skipper this (the definition of the connectstring
rule) does no longer compile. If I replace the rule by
  connectstring = id;
it does compile again (but of course not do what I want).

So there seems to be an issue (or misunderstanding on my part) with
raw/lexeme and whitespace skipping. Any insights are much appreciated!


Best regards
Christoph
[gram.cpp]

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_iso8859_1.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>


#include <list>
#include <string>

using std::string;
using boost::phoenix::bind;
using boost::phoenix::push_back;
using boost::phoenix::ref;
using boost::phoenix::val;
namespace qi = boost::spirit::qi;


//! Skips Whitespaces and C/C++-Comments.
template<typename Iterator>
struct skip_grammar : boost::spirit::qi::grammar<Iterator>
{
   skip_grammar() : skip_grammar::base_type(start)
      {
         using namespace boost::spirit::ascii;
         using boost::spirit::ascii::space;
         using boost::spirit::qi::eol;
         using boost::spirit::qi::char_;

         start =
              space                            // tab/space/cr/lf
            | "/*" >> *(char_ - "*/") >> "*/"  // C-style comments
            | "//" >> *(char_ - eol) >> eol    // C++-style comments
            ;
      }

   boost::spirit::qi::rule<Iterator> start;
};

template<typename Iterator, typename skipper=qi::unused_type>
struct config_grammar : qi::grammar<Iterator, skipper>
{
   config_grammar()
      : config_grammar::base_type(start)
   {
      using qi::lexeme;
      using qi::raw;
      using boost::spirit::ascii::alnum;
      using boost::spirit::ascii::alpha;

      start = id;

      id   %= raw[lexeme[ alpha >> +(alnum | '_' | '.') ]];
      // works only without the skipper
      connectstring %= raw[lexeme[id >> '/' >> id >> '@' >> id]];
      // compile fix: (but does obv. not do what I want)
      //connectstring = id;
   }
   qi::rule<const char*, skipper> start;
   qi::rule<const char*, skipper, std::string()> id, connectstring;
};

int main(int argc, char **argv)
{
   const char *first = argv[1];
   const char *last = argv[1]+strlen(argv[1]);

   try
   {
#if 0 // works without skipper
      config_grammar<const char*> grammar;
      bool bFailed = !qi::parse(first, last, grammar);
#else
      typedef skip_grammar<const char*> Skipper;
      config_grammar<const char*, Skipper> grammar;
      Skipper skip;
      bool bFailed = !qi::phrase_parse(first, last, grammar, skip);
#endif
   }
   catch (const std::exception &ex)
   {
      // pos=err.where.get_position();
      std::string error_cause = ex.what();
      std::cerr << "CAUGHT IT! " << error_cause << std::endl;
      return 1;
   }

   if (first != last)
   {
      std::cerr << "incomplete: " << std::string(first,last) << std::endl;
   }
   else std::cerr << "ok" << std::endl;

   return 0;
}


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Spirit-general mailing list
Spirit-general@...
https://lists.sourceforge.net/lists/listinfo/spirit-general

Re: [Spirit 2.1] strange problem with skipper

by Hartmut Kaiser :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> (See attachment for a (not) compilable exmaple illustrating the
> problem.
> I am using g++ 4.2.1)
>
> I have a simple rule
>
>   id            %= raw[lexeme[ alpha >> +(alnum | '_' | '.') ]];
>   connectstring %= raw[lexeme[id >> '/' >> id >> '@' >> id]];
>   start          = connectstring;
>
> which should parse stuff like "mike/test@host".
>
> This does compile and work - as long as I do NOT use a custom white
> space skipper.
> When I pass my whitespace skipper this (the definition of the
> connectstring
> rule) does no longer compile. If I replace the rule by
>   connectstring = id;
> it does compile again (but of course not do what I want).
>
> So there seems to be an issue (or misunderstanding on my part) with
> raw/lexeme and whitespace skipping. Any insights are much appreciated!

The rule 'id' is used inside a lexeme[], so it shouldn't have a skipper.
Changing your rule definitions to:

   qi::rule<const char*, skipper> start;
   qi::rule<const char*, skipper, std::string()> connectstring;
   qi::rule<const char*, std::string()> id;

resolves the problem.

Regards Hartmut

-------------------
Meet me at BoostCon
http://boostcon.com




------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Spirit-general mailing list
Spirit-general@...
https://lists.sourceforge.net/lists/listinfo/spirit-general

Re: [Spirit 2.1] strange problem with skipper

by Christoph Duelli :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hartmut Kaiser wrote:

>> I have a simple rule
>>
>>   id            %= raw[lexeme[ alpha >> +(alnum | '_' | '.') ]];
>>   connectstring %= raw[lexeme[id >> '/' >> id >> '@' >> id]];
>>   start          = connectstring;
>>
>> So there seems to be an issue (or misunderstanding on my part) with
>> raw/lexeme and whitespace skipping. Any insights are much appreciated!
>
> The rule 'id' is used inside a lexeme[], so it shouldn't have a skipper.
> Changing your rule definitions to:
>
>    qi::rule<const char*, skipper> start;
>    qi::rule<const char*, skipper, std::string()> connectstring;
>    qi::rule<const char*, std::string()> id;
>
> resolves the problem.
Yes, it does. Thank you.


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Spirit-general mailing list
Spirit-general@...
https://lists.sourceforge.net/lists/listinfo/spirit-general