我想弄清楚这个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.
但我写的表达似乎对我有用。我不确定它有什么问题。非常感谢任何帮助!
答案 0 :(得分:2)
您错过了标题。我不能说哪一个,但如果我只是包括
#include <boost/spirit/home/qi.hpp>
它编译。</ p>
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";
}
}