Search code examples
c++11boostg++boost-spirit

Error including boost/spirit/include/qi.hpp


I'm having the same error as occurs here. See 'compilation info' at the bottom for the long error message. Basically if I #include <boost/spirit/include/qi.hpp> I can't compile. Totally stumped by this one... I am compiling with g++ 4.9.3 on Debian using C++11. For reference the first part of the error message is:

In file included from /usr/include/boost/spirit/home/qi/nonterminal/rule.hpp:35:0,
             from /usr/include/boost/spirit/home/qi/nonterminal.hpp:14,
             from /usr/include/boost/spirit/home/qi.hpp:20,
             from /usr/include/boost/spirit/include/qi.hpp:16,
             from prog.cpp:9:
/usr/include/boost/spirit/home/qi/reference.hpp: In instantiation of 'bool boost::spirit::qi::reference<Subject>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; Context = boost::spirit::context<boost::fusion::cons<std::basic_string<char>&, boost::fusion::nil_>, boost::spirit::locals<> >; Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >; Attribute = std::basic_string<char>; Subject = const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::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> >, 0l>, boost::spirit::unused_type, boost::spirit::unused_type>]':

My code is actually a little bit different to the above example:

My::Dictionary Parser::parse( const char * s ) {
  std::string input(s);     // input to parse
  qi_my_protocol grammar;   // create instance of parser
  My::Dictionary msg;      // map to receive results
  bool result = qi::phrase_parse(
    input.begin(),
    input.end(),
    grammar,
    qi::space,
    msg
  ); // returns true if successful
  return msg;
}

Solution

  • Your string isn't const, so the iterators first and last aren't const iterators.

    Either make the my_Parse function not a template (after all, you hardcode the iterator type on the grammar to be std::string::const_iterator anyways), or instantiate the grammar with the actual iterator type:

    my_grammar<Iterator> g;
    

    Live On Coliru

    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/include/phoenix.hpp>
    
    #include <stdio.h>
    
    namespace qi =       boost::spirit::qi;
    namespace ascii =    boost::spirit::ascii;
    namespace phoenix =  boost::phoenix;
    
    template <typename Iterator>
    struct my_grammar : boost::spirit::qi::grammar<Iterator, std::string(), ascii::space_type>
    {
    
        my_grammar() : my_grammar::base_type(start)
        {
            using qi::alpha;
            using qi::alnum;
    
            start %=
                (+alpha | +alnum)
                ;
        }
    
        qi::rule<Iterator, std::string(), ascii::space_type> start;
    };
    
    template <typename Iterator>
    bool my_Parse(Iterator first, Iterator last, std::string& result)
    {
        using boost::spirit::ascii::space;
    
        my_grammar<Iterator> g;
    
        bool r = phrase_parse(first, last, g, space, result);
    
        if (!r || first != last) // fail if we did not get a full match
            return false;
    
        return r;
    }
    
    
    
    int main() {
        std::string str;
        while (getline(std::cin, str))
        {
            std::string result = "";
            if (my_Parse(str.begin(), str.end(), result))
            {
                std::cout << "-------------------------\n";
                std::cout << "Parsing succeeded\n";
                std::cout << "got: " << result << std::endl;
                std::cout << "\n-------------------------\n";
            }
            else
            {
                std::cout << "-------------------------\n";
                std::cout << "Parsing failed\n";
                std::cout << "-------------------------\n";
            }
        }
    }