I would like to use a Spirit Qi grammar to parse text into shared pointers to strings. Actually, I would like to parse multivariate polynomials into a system of them, with various kinds of previously-encountered symbols appearing in the polynomials, but for now, let's parse from text into std::shared_ptr<std::string>
.
I have been floundering for a long time now, and have distilled this small test grammar in a header file:
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/bind.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template<typename Iterator>
struct SharedPtrParser : qi::grammar<Iterator, std::shared_ptr<std::string>(), boost::spirit::ascii::space_type>
{
SharedPtrParser() : SharedPtrParser(startrule)
{
startrule = qi::eps[ qi::_val = std::make_shared<std::string>()];
}
qi::rule<Iterator,std::shared_ptr<std::string>()> startrule;
};
and this usage of it in main:
#include "shared_ptr_test.h"
int main()
{
SharedPtrParser<std::string::const_iterator> C;
std::string text = "thisissometext";
auto iter = text.begin();
auto end = text.end();
std::shared_ptr<std::string> S;
bool s = phrase_parse(iter, end, C,boost::spirit::ascii::space, S);
return 0;
}
I am aware that my grammar doesn't do squat. I just want to make shared pointers from Qi right now! To this end, I've found a number of hints regarding using smart pointers in conjunction with Qi, but no grammars which are factories for them. I feel like I've been close, especially having found this post by sehe from Spirit General discussion forum. However, I just haven't been able to put it together yet.
Attempts at compilation produce two errors as written ATM.
one:
./shared_ptr_test.h:16:22: error: no matching constructor for initialization of 'SharedPtrParser<std::__1::__wrap_iter<const char *> >'
SharedPtrParser() : SharedPtrParser(startrule)
^ ~~~~~~~~~
shared_ptr_test.cpp:8:47: note: in instantiation of member function 'SharedPtrParser<std::__1::__wrap_iter<const char *> >::SharedPtrParser' requested here
SharedPtrParser<std::string::const_iterator> C;
^
./shared_ptr_test.h:14:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'qi::rule<__wrap_iter<const char *>,
std::shared_ptr<std::string> ()>' to 'const SharedPtrParser<std::__1::__wrap_iter<const char *> >' for 1st argument
struct SharedPtrParser : qi::grammar<Iterator, std::shared_ptr<std::string>(), boost::spirit::ascii::space_type>
^
./shared_ptr_test.h:16:2: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
SharedPtrParser() : SharedPtrParser(startrule)
^
two:
In file included from shared_ptr_test.cpp:1:
In file included from ./shared_ptr_test.h:4:
In file included from /usr/local/include/boost/spirit/include/qi.hpp:16:
In file included from /usr/local/include/boost/spirit/home/qi.hpp:21:
In file included from /usr/local/include/boost/spirit/home/qi/nonterminal.hpp:14:
In file included from /usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:35:
/usr/local/include/boost/spirit/home/qi/reference.hpp:43:30: error: no matching member function for call to 'parse'
return ref.get().parse(first, last, context, skipper, attr_);
~~~~~~~~~~^~~~~
/usr/local/include/boost/spirit/home/qi/parse.hpp:164:40: note: in instantiation of function template specialization 'boost::spirit::qi::reference<const
boost::spirit::qi::rule<std::__1::__wrap_iter<const char *>, std::__1::shared_ptr<std::__1::basic_string<char> > (),
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>, boost::spirit::unused_type, boost::spirit::unused_type> >::parse<std::__1::__wrap_iter<char *>,
boost::spirit::context<boost::fusion::cons<std::__1::shared_ptr<std::__1::basic_string<char> > &, boost::fusion::nil_>, boost::spirit::locals<mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,
boost::spirit::char_encoding::ascii> >, std::__1::shared_ptr<std::__1::basic_string<char> > >' requested here
if (!compile<qi::domain>(expr).parse(
^
/usr/local/include/boost/spirit/home/qi/parse.hpp:197:20: note: in instantiation of function template specialization 'boost::spirit::qi::phrase_parse<std::__1::__wrap_iter<char *>,
SharedPtrParser<std::__1::__wrap_iter<const char *> >, 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>, std::__1::shared_ptr<std::__1::basic_string<char>
> >' requested here
return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip, attr);
^
shared_ptr_test.cpp:18:11: note: in instantiation of function template specialization 'boost::spirit::qi::phrase_parse<std::__1::__wrap_iter<char *>,
SharedPtrParser<std::__1::__wrap_iter<const char *> >, 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>, std::__1::shared_ptr<std::__1::basic_string<char>
> >' requested here
bool s = phrase_parse(iter, end, C,boost::spirit::ascii::space, S);
^
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:274:14: note: candidate function [with Context =
boost::spirit::context<boost::fusion::cons<std::__1::shared_ptr<std::__1::basic_string<char> > &, boost::fusion::nil_>, boost::spirit::locals<mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,
boost::spirit::char_encoding::ascii> >, Attribute = std::__1::shared_ptr<std::__1::basic_string<char> >] not viable: no known conversion from 'std::__1::__wrap_iter<char *>' to
'std::__1::__wrap_iter<const char *> &' for 1st argument
bool parse(Iterator& first, Iterator const& last
^
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:320:14: note: candidate function template not viable: requires 6 arguments, but 5 were provided
bool parse(Iterator& first, Iterator const& last
A little help?
My problem here was trivial and noobish. I failed to specify for the constructor, ::base_type
. That is, the line for SharedPtrParser() : SharedPtrParser(startrule)
should have been SharedPtrParser() : SharedPtrParser::base_type(startrule)
.