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?
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://stackoverflow.com/a/8534840/2524462 how to do that.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With