在一个简单的boost.spirit示例中,error_invalid_expression编译错误

时间:2014-03-23 06:51:02

标签: c++ visual-c++ boost-spirit

我正在尝试在Visual Studio 2013上开始使用boost.spirit,我收到error_invalid_expression编译错误。这是代码:

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

void main()
{
  using namespace boost::spirit::qi;

  std::string in("123 234");
  std::cout << parse(in.begin(), in.end(), int_) << '\n';                // works fine
  std::cout << parse(in.begin(), in.end(), int_ << ' ' << int_) << '\n'; // error here
}

这是模板barf:

C:\boost\boost/spirit/home/qi/detail/parse.hpp(32): error C2338: error_invalid_expression
          C:\boost\boost/spirit/home/qi/parse.hpp(36) : see reference to class template instantiation 'boost::spirit::qi::detail::parse_impl<Expr,void>' being compiled
          with
          [
              Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::int_> &,boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char &>,0>>,2> &,const boost::spirit::terminal<boost::spirit::tag::int_> &>,2>
          ]
          C:\boost\boost/spirit/home/qi/parse.hpp(47) : see reference to function template instantiation 'bool boost::spirit::qi::parse<std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,boost::proto::exprns_::expr<Tag,Args,2>>(Iterator &,Iterator,const Expr &)' being compiled
          with
          [
              Tag=boost::proto::tagns_::tag::shift_left
  ,            Args=boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::int_> &,boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char &>,0>>,2> &,const boost::spirit::terminal<boost::spirit::tag::int_> &>
  ,            Iterator=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>
  ,            Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::int_> &,boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char &>,0>>,2> &,const boost::spirit::terminal<boost::spirit::tag::int_> &>,2>
          ]
          Spirit.cpp(12) : see reference to function template instantiation 'bool boost::spirit::qi::parse<std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,boost::proto::exprns_::expr<Tag,Args,2>>(const Iterator &,Iterator,const Expr &)' being compiled
          with
          [
              Tag=boost::proto::tagns_::tag::shift_left
  ,            Args=boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::int_> &,boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char &>,0>>,2> &,const boost::spirit::terminal<boost::spirit::tag::int_> &>
  ,            Iterator=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>
  ,            Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::int_> &,boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char &>,0>>,2> &,const boost::spirit::terminal<boost::spirit::tag::int_> &>,2>
          ]
C:\boost\boost/spirit/home/qi/parse.hpp(36): error C2039: 'call' : is not a member of 'boost::spirit::qi::detail::parse_impl<Expr,void>'
          with
          [
              Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::int_> &,boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char &>,0>>,2> &,const boost::spirit::terminal<boost::spirit::tag::int_> &>,2>
          ]
C:\boost\boost/spirit/home/qi/parse.hpp(36): error C3861: 'call': identifier not found

我尝试添加上面提到的各种包含文件,但它没有帮助。任何想法这个代码有什么问题?

2 个答案:

答案 0 :(得分:1)

我在复制示例时使用了错误的移位运算符:<<而不是>>。它应该是:

std::cout << parse(in.begin(), in.end(), int_ >> ' ' >> int_) << '\n';

模板错误消息像往常一样有用: - (

答案 1 :(得分:1)

@Paul你有我的所有权利抱怨:)

我只是指出它可能会更糟糕(而且经常是这样),并且你实际上可以感谢图书馆编写者使这个问题可以追溯。

现在从&#34; tag :: shift_left&#34;跳转到operator<<是唯一棘手的部分。

其余的我想指向模板barf 证据:

  • 第一行报告

      

    C:\boost\boost/spirit/home/qi/detail/parse.hpp(32): error C2338: error_invalid_expression

    让我们来看看:

    • error_invalid_expression试图告诉你,你正在尝试编译一个你不应该尝试编译的表达式。
    • 错误源自qi/detail/parse.hpp(32)。这会立即告诉你它在一个Boost Spirit Qi表达中(而不是,例如在一个Karma表达式中)。


    第一行上的双击会将您带到此位置,该位置显示为:

    {
        // Report invalid expression error as early as possible.
        // If you got an error_invalid_expression error message here,
        // then the expression (expr) is not a valid spirit qi expression.
        // Did you intend to use the auto_ facilities while forgetting to 
        // #include <boost/spirit/include/qi_auto.hpp>?
        BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr); // <-- LINE 32
    };
    

我想我的意思是:不要抱怨,而只是吸收新的方式来阅读&#34;消息。当然,你有权投诉,就像你开始使用锤子敲打地毯时,你的指甲开始弯曲一样可以抱怨。

我只是觉得有必要警告,如果你不能忍受你在这种情况下获得的信息,那么可能Boost Spirit(或任何其他Boost Proto,Boost Mpl和Boost Fusion重型图书馆)可能不是你的的事情。

我使用Coco/R C++进行解析器生成有非常愉快的体验。还有其他(灵魂/野牛,ANTLR浮现在脑海中)。所有上述内容都适用于较大的语法,并具有额外的好处,例如:

  • 语法规范在不同开发语言中的可移植性
  • 有助于测试/转换/诊断语法的工具
  • 大大减少了编译时间。

我说这是常驻爱好者之一(citation)。

明智地选择你的工具。并且不要将个人偏好作为一个因素。