提升精神编译错误" error_invalid_expression"

时间:2018-01-29 20:51:36

标签: c++ boost boost-spirit

我想弄清楚这个Boost Spirit代码有什么问题:

#include <iostream>
#include <string>

#include <boost/spirit/include/qi_uint.hpp>
#include <boost/spirit/include/qi_grammar.hpp>

template <typename Iterator>
struct Header
{
    struct Type : boost::fusion::vector2<unsigned int, unsigned int>
    {
        unsigned int getFirstThing() { return boost::fusion::at_c<0>(*this); }
        unsigned int getSecondThing() { return boost::fusion::at_c<1>(*this); }
    };
};

template<typename Iterator>
struct HeaderParse
    : boost::spirit::qi::grammar<Iterator, typename Header<Iterator>::Type() >
{
    HeaderParse()
        : HeaderParse::base_type(_start)
    {
        using boost::spirit::qi::uint_parser;

        _start = '<' 
            >> uint_parser<unsigned int, 10, 1, 3>() 
            >> '>'
            >> uint_parser<unsigned int, 10, 1, 3>();

        _start.name("HeaderParse");
    }   

    ~HeaderParse() = default;

    boost::spirit::qi::rule<Iterator, typename Header<Iterator>::Type() > _start;
};

int main()
{
    const std::string d1 = "<1>2";

    const HeaderParse<std::string::const_iterator> parser;
    Header<std::string::const_iterator>::Type header;

    std::string::const_iterator begin = d1.begin();
    std::string::const_iterator end = d1.end();

    assert(boost::spirit::qi::parse(begin, end, parser, header));
    return 0;
}

这是我在尝试编译时看到的编译错误:

$ make --jobs=8
Scanning dependencies of target testapp
[ 50%] Building CXX object CMakeFiles/testapp.dir/test.cpp.o
In file included from /Users/addy/nw/stub/test.cpp:5:
In file included from /Users/addy/Downloads/boost_1_65_1/boost/spirit/include/qi_grammar.hpp:16:
In file included from /Users/addy/Downloads/boost_1_65_1/boost/spirit/home/qi/nonterminal/grammar.hpp:18:
/Users/addy/Downloads/boost_1_65_1/boost/spirit/home/qi/nonterminal/rule.hpp:177:13: error: static_assert failed "error_invalid_expression"
            BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...

/Users/aclaure/nw/stub/test.cpp:27:16: note: in instantiation of function template specialization 'boost::spirit::qi::rule<std::__1::__wrap_iter<const char *>,
      Header<std::__1::__wrap_iter<const char *> >::Type (), boost::spirit::unused_type, boost::spirit::unused_type,
      boost::spirit::unused_type>::operator=<boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right, boost::proto::argsns_::list2<const
      boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,
      boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right, boost::proto::argsns_::list2<const
      boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::terminal_ex<boost::spirit::tag::lit, boost::fusion::vector<char
      const (&)[7]> > >, 0> &, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<const char &>, 0> >, 2> &, const
      boost::spirit::qi::uint_parser<unsigned int, 10, 1, 3> &>, 2> &, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<const char &>, 0>
      >, 2> &, const boost::spirit::qi::uint_parser<unsigned int, 10, 1, 3> &>, 2> >' requested here
        _start = 
               ^
/Users/aclaure/nw/stub/test.cpp:46:52: note: in instantiation of member function 'HeaderParse<std::__1::__wrap_iter<const char *> >::HeaderParse' requested here
    const HeaderParse<std::string::const_iterator> parser;

这导致我在Spirit头文件中发表此评论:

        // 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.

但我写的表达似乎对我有用。我不确定它有什么问题。非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

您错过了标题。我不能说哪一个,但如果我只是包括

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

它编译。<​​/ p>

Live example on Wandbox

N.B。:我无法找到任何“官方”声明,但我不认为包括个别标题是推荐的。至少没有一个Qi的例子可以做到。

我猜你只包含那些标题,因为你希望以这种方式减少编译时间。如果你真的想加快速度,可以考虑使用X3。这个例子在我的机器上编译大约需要1秒。

#include <iostream>
#include <string>
#include <tuple>

#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted.hpp>

namespace Header {

using Type = std::tuple<unsigned int, unsigned int>;

namespace x3 = boost::spirit::x3;

x3::uint_parser<unsigned int, 10, 1, 3> uint_;

x3::rule<class parser, Type> const parser = "parser";
auto const parser_def  = '<' >> uint_ >> '>' >> uint_;

BOOST_SPIRIT_DEFINE(parser)

}

int main()
{
    const std::string d1 = "<1>2";

    Header::Type header;

    auto iter = d1.begin();
    auto end = d1.end();

    bool r = boost::spirit::x3::parse(iter, end, Header::parser, header);
    if (!r || iter != end) {
        std::cerr << "Parsing failed at " << std::string{iter,end} << "\n";
    } else {
        std::cout << std::get<0>(header) << " " << std::get<1>(header) << "\n";
    }
}

Live example on Wandbox

相关问题