Boost Spirit kwd parser in Visual Studio 2013

443 views Asked by At

I'm using Boost 1.57 with Visual Studio 2010.

I would like to upgrade my project to Visual Studio 2013 but i'm having some problem with the boost Spirit parser. Seem to me that the kwd parser is broken somehow. The following code compiles correctly in Visual Studio 2010:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/repository/include/qi_kwd.hpp>
#include <boost/spirit/repository/include/qi_keywords.hpp>
#include <iostream>
#include <string>
using boost::spirit::qi::double_;
using boost::spirit::qi::_1;
using boost::phoenix::ref;
using boost::spirit::repository::qi::kwd;

template <typename Iterator>
bool difference(Iterator first, Iterator last, double& n) {
    bool r = boost::spirit::qi::phrase_parse(first, last,
             //the grammar
             (kwd("A")[double_[ref(n) += _1]] /
              kwd("B")[double_ [ref(n) -= _1]]),
                              boost::spirit::ascii::space);
    if (first != last) return false;
    return r;
}

int main() {
    std::string str("A 1 B 2");
    double n=0;
    std::cout << "Full parse: " << difference(str.begin(), str.end(), n) << std::endl;  
    std::cout << "A - B = " << n <<std::endl;
    return 0;
}

The errors I get wnen i try to compile it with Visual Studio 2013 are (among the many):

 Error  3   error C3203: 'type' : unspecialized class template can't be used as a template argument for template parameter 'T2', expected a real type   ... fold_impl.hpp   
 Error  4   error C2039: 'type' : is not a member of 'boost::mpl::apply<boost::fusion::detail::apply_transform_result<boost::spirit::repository::qi::detail::string_keywords<Elements,boost::mpl::filter_view<Elements,boost::spirit::repository::qi::is_kwd_parser<boost::mpl::_>>,boost::mpl::filter_view<boost::mpl::vector2<boost::mpl::integral_c<T,0>,boost::mpl::integral_c<T,1>>,boost::spirit::repository::qi::keywords<Elements,Modifiers>::is_kwd_parser_filter<boost::mpl::_>>,boost::array<bool,2>,Modifiers>::build_char_type_sequence<StringKeywords>::element_char_type>,boost::spirit::repository::qi::kwd_parser<Subject,const char (&),boost::spirit::qi::make_directive_internal<T1,Subject,Modifiers,boost::mpl::false_>::iterator_type,boost::spirit::has_modifier<Modifiers,boost::spirit::tag::char_code_base<CharClass>>,Distinct>,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>'   ... value_of_impl.hpp   

Is this a bug of Boost? Is there any way to get this code to compile in Visual Studio 2013? (of course my real project is much bigger than this, it would be a problem to rewrite all the grammar)

Any help is appreciated.

1

There are 1 answers

2
sehe On BEST ANSWER

The problem appears to be that the mpl/fusion libraries have shifted to no longer expecting to TR1 result-of protocol.

This has everything to do with the fact that compilers at large have implemented decltype support, and in fact

  • BOOST_RESULT_OF_USE_DECLTYPE has become the default boost config for most compilers
  • Phoenix V3 has become the default for Spirit in recent versions

I verified that your particular sample does compile on clang when you insert this line at the top:

#define BOOST_RESULT_OF_USE_TR1

See it Live On Coliru

Actually this still represents a problem that should be reported to the Spirit mailing list, IMO as TR1 protocol will certainly be obsoleted in the future.

In the meantime, I suggest to use TR1 as a fallback only:

#define BOOST_RESULT_OF_USE_DECLTYPE_WITH_TR1_FALLBACK

See it Live On Coliru too.

NOTE

In order to compile with VS2013, I had to also add the following define

#define _SCL_SECURE_NO_WARNINGS

enter image description here