Search code examples
c++c++11boostcompiler-errorsboost-spirit

Compile-time error when trying to parse a Boost Spirit grammar


Trying to compile the following code (a minimal example created from my original code) gives the error listed below.

The problem seems to be with the line qi::phrase_parse(first, str.end(), grammar, ascii::blank);, but I have no clue what could be wrong with this. Removing that line causes the code to compile successfully, so it seems there is nothing wrong with the grammar definition itself.

This SO question reports a similar error, but I can't find anything applicable in the answer.

#include <boost/spirit/include/qi.hpp>
#include <string>

using namespace std;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Iterator>
class DoubleGrammar : qi::grammar<Iterator, ascii::blank_type> {
private:
    qi::rule<Iterator, ascii::blank_type> double_rule;
public:
    DoubleGrammar() : DoubleGrammar::base_type(double_rule) {
        double_rule = qi::double_;
    }
};

int main(int argc, char** argv) {
    DoubleGrammar<string::iterator> grammar;
    string str = "1.0";
    string::iterator first = str.begin();
    qi::phrase_parse(first, str.end(), grammar, ascii::blank);
    return 0;
}

Compiler output:

In file included from /usr/include/boost/proto/traits.hpp:24:0,
                 from /usr/include/boost/proto/expr.hpp:27,
                 from /usr/include/boost/proto/core.hpp:17,
                 from /usr/include/boost/proto/proto.hpp:12,
                 from /usr/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /usr/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /usr/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /usr/include/boost/spirit/home/qi/action.hpp:14,
                 from /usr/include/boost/spirit/home/qi.hpp:14,
                 from /usr/include/boost/spirit/include/qi.hpp:16,
                 from .build/test/spirittest.cpp:4:
/usr/include/boost/spirit/home/qi/detail/parse.hpp: In instantiation of 'struct boost::spirit::qi::detail::phrase_parse_impl<DoubleGrammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >, void>':
/usr/include/boost/spirit/home/qi/detail/parse_auto.hpp:186:50:   required from 'bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, Expr&, const Skipper&, boost::spirit::qi::skip_flag) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; Expr = DoubleGrammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >; Skipper = 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::ascii> >, 0l>]'
.build/test/spirittest.cpp:62:61:   required from here
/usr/include/boost/spirit/home/qi/detail/parse.hpp:59:9: error: static assertion failed: error_invalid_expression
         BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
         ^
In file included from /usr/include/boost/spirit/home/qi/auto.hpp:16:0,
                 from /usr/include/boost/spirit/home/qi.hpp:15,
                 from /usr/include/boost/spirit/include/qi.hpp:16,
                 from .build/test/spirittest.cpp:4:
/usr/include/boost/spirit/home/qi/detail/parse_auto.hpp: In instantiation of 'bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, Expr&, const Skipper&, boost::spirit::qi::skip_flag) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; Expr = DoubleGrammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >; Skipper = 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::ascii> >, 0l>]':
.build/test/spirittest.cpp:62:61:   required from here
/usr/include/boost/spirit/home/qi/detail/parse_auto.hpp:186:50: error: 'call' is not a member of 'boost::spirit::qi::detail::phrase_parse_impl<DoubleGrammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >, void>'
             first, last, expr, skipper, post_skip);
                                                  ^

Solution

  • I actually found the answer with the help of this SO answer I found in the related questions list.

    The problem was that the DoubleGrammar class inherited qi::grammar privately. Adding a public visibility specifier solved the problem.

    This went wrong because the example on which it was based used a struct, which has public visibility by default.