[Qi] Bizarro Qi results coming from compiler
Michael Powell <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <CAMEoF_Ft-oD8rYrKjGx_QVLeX9pte7w8uYk3-6=Xcz2=+gjuLw@mail.gmail.com> |
I am receiving bizarro error coming from Spirit (latest stable Boost
release, Visual Studio 2015, but also via Coliru, and Wandbox, gcc).
Severity Code Description Project File Line Suppression State
Error C2664 'bool boost::function4<R,T0,T1,T2,T3>::operator
()(T0,T1,T2,T3) const': cannot convert argument 4 from 'const
skipper_type' to 'const boost::spirit::qi::reference<const
boost::spirit::qi::rule<Iterator,T1,T2,T3,T4>> &'
Rfc3986_Uri_RegexSyntaxVerification
G:\Source\Boost.Installs\boost_1_65_1\boost\spirit\home\qi\nonterminal\rule.hpp
304
// ...
template<typename Iterator>
struct my_skipper : qi::grammar<Iterator> {
qi::rule<Iterator> _skip;
my_skipper() : my_skipper::base_type(_skip) {
using namespace boost::spirit::qi;
_skip = ascii::space;
}
};
template<typename Iterator, typename Skipper = my_skipper<Iterator>>
struct my_port : qi::grammar<Iterator, std::uint16_t(), Skipper> {
qi::rule<Iterator, std::uint16_t(), Skipper> _start;
my_port() : my_port::base_type(_start), _start() {
using std::uint16_t;
using qi::uint_parser;
using qi::lexeme;
_start = lexeme[uint_parser<uint16_t, 10, 1, 5>()];
}
};
// ...
my_port<std::string::const_iterator> port_g_;
auto& space_ = boost::spirit::qi::ascii::space;
auto const& parse_port_ = [&port_g_, &space_](std::string const& s,
std::uint16_t const& y, bool expected_parsed) {
auto it = s.begin();
std::uint16_t x;
auto const actual_parsed = phrase_parse(it, s.end(), port_g_, space_, x);
};
parse_port_("12345", 12345, true);
parse_port_("abc", -1, false);
I followed through on the reasons given here, but it just does not hold water.
https://stackoverflow.com/questions/21672316/boost-spirit-skipper-compile-time-error
Particularly the idiotic comments concerning:
// If you are seeing a compilation error here stating that the
// fourth parameter can't be converted to a required target type
// then you are probably trying to use a rule or a grammar with
// an incompatible skipper type.
if (f(first, last, context, skipper))
I assure you, I ***have*** set the skipper, and it **DOES NOT WORK**
with parse_phrase, and I'm not sure as to **WHY**.
Can someone shed some light on this? Should I be skipping at all? How
does something like this work in my production grammar, and not now
that I am trying to vet a more complex issue, starting from this
"simple" one? Which, from what I can tell, is effectively the same as
the one I've already tested in my production code?
template<typename Iterator, typename Skipper =
boost::spirit::qi::ascii::space_type>
struct PortParser : boost::spirit::qi::grammar<Iterator,
std::uint16_t(), Skipper> {
boost::spirit::qi::rule<Iterator, std::uint16_t(), Skipper> _start;
PortParser() : PortParser::base_type(_start), _start() {
using std::string;
using std::uint16_t;
using std::numeric_limits;
using boost::lexical_cast;
using boost::spirit::qi::lexeme;
using boost::spirit::qi::uint_parser;
_start = lexeme[uint_parser<uint16_t, 10, 1, 5>()];
typedef numeric_limits<uint16_t> Limits;
_start.name("a valid port number from "
+ lexical_cast<string>(Limits::min())
+ " through " + lexical_cast<string>(Limits::max()));
}
};
It just doesn't make sense to me.
Cheers,
Michael Powell
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot