boost spirit skipper - compile-time error
Asked Answered
D

2

5

I have the following code:

#include <boost/fusion/include/define_struct.hpp>
#include <boost/spirit/include/qi.hpp>

#include <iostream>
#include <string>

BOOST_FUSION_DEFINE_STRUCT(
  (), foo,
  (int, bar)
  (int, baz)
)

template <typename Iterator>
struct parser : boost::spirit::qi::grammar<Iterator, foo(), boost::spirit::qi::ascii::space_type>
{
  parser() : parser::base_type(start)
  {
    start %= boost::spirit::qi::int_ >> boost::spirit::qi::int_;
  }

  boost::spirit::qi::rule<Iterator, foo(), boost::spirit::qi::ascii::space_type> start;
};

int main()
{
  const std::string input_data("0 1");

  foo instance;
  auto itr = input_data.begin();
  auto end = input_data.end();
  parser<decltype(itr)> g;
  bool res = boost::spirit::qi::phrase_parse(
    itr
    , end
    , g
    , (
        boost::spirit::ascii::space
        | ("//" >> *(boost::spirit::qi::char_ - boost::spirit::qi::eol) >> boost::spirit::qi::eol | boost::spirit::qi::blank)
      )
    , instance
  );
  if (res && itr == end)
  {
    std::cout << "Parsing succeeded \n";
    std::cout << instance.bar << ' ' << instance.baz << '\n';
  }
  else
  {
    std::cout << "Parsing failed \n";
  }
}

It gives me the following error:

1>e:\libs\boost_1_54_0\boost\spirit\home\qi\nonterminal\rule.hpp(303): error C2664: 'bool boost::function4<R,T0,T1,T2,T3>::operator ()(T0,T1,T2,T3) const' : cannot convert parameter 4 from 'const skipper_type' to 'const boost::spirit::qi::char_class<Tag> '
1>          with
1>          [
1>              R=bool,
1>              T0=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>> &,
1>              T1=const std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>> &,
1>              T2=boost::spirit::context<boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,boost::fusion::vector0<>> &,
1>              T3=const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>> &
1>          ]
1>          and
1>          [
1>              Tag=boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>
1>          ]
1>          Reason: cannot convert from 'const skipper_type' to 'const boost::spirit::qi::char_class<Tag>'
1>          with
1>          [
1>              Tag=boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>
1>          ]
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>          e:\libs\boost_1_54_0\boost\spirit\home\qi\reference.hpp(43) : see reference to function template instantiation 'bool boost::spirit::qi::rule<Iterator,T1,T2,T3,T4>::parse<Context,Skipper,Attribute>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1>          with
1>          [
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              T1=`anonymous-namespace'::foo (void),
1>              T2=boost::spirit::ascii::space_type,
1>              T3=boost::spirit::unused_type,
1>              T4=boost::spirit::unused_type,
1>              Context=boost::spirit::context<boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,boost::spirit::locals<>>,
1>              Skipper=skipper_type,
1>              Attribute=`anonymous-namespace'::foo
1>          ]
1>          e:\libs\boost_1_54_0\boost\spirit\home\qi\reference.hpp(43) : see reference to function template instantiation 'bool boost::spirit::qi::rule<Iterator,T1,T2,T3,T4>::parse<Context,Skipper,Attribute>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1>          with
1>          [
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              T1=`anonymous-namespace'::foo (void),
1>              T2=boost::spirit::ascii::space_type,
1>              T3=boost::spirit::unused_type,
1>              T4=boost::spirit::unused_type,
1>              Context=boost::spirit::context<boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,boost::spirit::locals<>>,
1>              Skipper=skipper_type,
1>              Attribute=`anonymous-namespace'::foo
1>          ]
1>          e:\libs\boost_1_54_0\boost\spirit\home\qi\parse.hpp(165) : see reference to function template instantiation 'bool boost::spirit::qi::reference<Subject>::parse<Iterator,boost::spirit::context<Attributes,Locals>,skipper_type,Attr>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1>          with
1>          [
1>              Subject=const boost::spirit::qi::rule<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,`anonymous-namespace'::foo (void),boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type>,
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              Attributes=boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,
1>              Locals=boost::spirit::locals<>,
1>              Attr=`anonymous-namespace'::foo,
1>              Context=boost::spirit::context<boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,boost::spirit::locals<>>,
1>              Skipper=skipper_type,
1>              Attribute=`anonymous-namespace'::foo
1>          ]
1>          e:\libs\boost_1_54_0\boost\spirit\home\qi\parse.hpp(165) : see reference to function template instantiation 'bool boost::spirit::qi::reference<Subject>::parse<Iterator,boost::spirit::context<Attributes,Locals>,skipper_type,Attr>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1>          with
1>          [
1>              Subject=const boost::spirit::qi::rule<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,`anonymous-namespace'::foo (void),boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type>,
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              Attributes=boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,
1>              Locals=boost::spirit::locals<>,
1>              Attr=`anonymous-namespace'::foo,
1>              Context=boost::spirit::context<boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,boost::spirit::locals<>>,
1>              Skipper=skipper_type,
1>              Attribute=`anonymous-namespace'::foo
1>          ]
1>          e:\libs\boost_1_54_0\boost\spirit\home\qi\parse.hpp(197) : see reference to function template instantiation 'bool boost::spirit::qi::phrase_parse<Iterator,Expr,Skipper,Attr>(Iterator &,Iterator,const Expr &,const Skipper &,boost::spirit::qi::skip_flag,Attr &)' being compiled
1>          with
1>          [
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              Expr=parser<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>,
1>              Skipper=boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>>,0> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char (&)[3]>,0>,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference,boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::minus,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::standard::char_> ,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &>,1> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank,boost::spirit::char_encoding::standard>>,0> &>,2> &>,2>,
1>              Attr=`anonymous-namespace'::foo
1>          ]
1>          e:\work\projects\src\min\min\main.cpp(13803) : see reference to function template instantiation 'bool boost::spirit::qi::phrase_parse<std::_String_const_iterator<_Mystr>,parser<Iterator>,boost::proto::exprns_::expr<Tag,Args,Arity>,`anonymous-namespace'::foo>(Iterator &,Iterator,const Expr &,const Skipper &,Attr &)' being compiled
1>          with
1>          [
1>              _Mystr=std::_String_val<std::_Simple_types<char>>,
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              Tag=boost::proto::tagns_::tag::bitwise_or,
1>              Args=boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>>,0> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char (&)[3]>,0>,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference,boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::minus,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::standard::char_> ,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &>,1> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank,boost::spirit::char_encoding::standard>>,0> &>,2> &>,
1>              Arity=2,
1>              Expr=parser<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>,
1>              Skipper=boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>>,0> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char (&)[3]>,0>,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference,boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::minus,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::standard::char_> ,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &>,1> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank,boost::spirit::char_encoding::standard>>,0> &>,2> &>,2>,
1>              Attr=`anonymous-namespace'::foo
1>          ]

This is a result of adding

("//" >> *(boost::spirit::qi::char_ - boost::spirit::qi::eol) >> boost::spirit::qi::eol | boost::spirit::qi::blank)

What am I doing wrong? How can I fix it?

Do answered 10/2, 2014 at 8:37 Comment(0)
S
6

Indeed, your skipper is not of the correct type.

Change it e.g.:

#include <boost/fusion/include/define_struct.hpp>
#include <boost/spirit/include/qi.hpp>

#include <iostream>
#include <string>

namespace qi = boost::spirit::qi;

BOOST_FUSION_DEFINE_STRUCT(
  (), foo,
  (int, bar)
  (int, baz)
)

template <typename Iterator, typename Skipper>
    struct parser : qi::grammar<Iterator, foo(), Skipper>
{
    parser() : parser::base_type(start)
    {
        start %= qi::int_ >> qi::int_;
    }

    qi::rule<Iterator, foo(), Skipper> start;
};

int main()
{
  const std::string input_data("0 1");

  foo instance;
  auto itr = input_data.begin();
  auto end = input_data.end();

  qi::rule<decltype(itr)> skipper = 
          qi::ascii::space 
        | ("//" >> *(qi::char_ - qi::eol) >> qi::eol | qi::blank);

  parser<decltype(itr), decltype(skipper)> g;

  bool res = qi::phrase_parse(itr, end, g, skipper, instance);

  if (res && itr == end)
  {
      std::cout << "Parsing succeeded \n";
      std::cout << instance.bar << ' ' << instance.baz << '\n';
  }
  else
  {
      std::cout << "Parsing failed \n";
  }
}

See it Live On Coliru

Seraphim answered 10/2, 2014 at 10:49 Comment(2)
can you give me your email / skype, please? I don't see such info in your StackExchange profileDo
@Do Others have been able to find it :) Generally I prefer to keep my 'support' activities around SO. I can of course add a 'Donate' button to my profile bio :)Seraphim
F
5

Your skipper type is still boost::spirit::qi::ascii::space_type although you changed your skipper to

boost::spirit::ascii::space
| ("//" >> *(boost::spirit::qi::char_ - boost::spirit::qi::eol) >>   boost::spirit::qi::eol | boost::spirit::qi::blank)

Just put your rule in a separate skipper component and use the type of it. A quick search gave this example https://mcmap.net/q/636817/-custom-skip-parser-with-boost-spirit how to do that.

Fane answered 10/2, 2014 at 10:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.