【发布时间】:2013-11-18 11:38:14
【问题描述】:
请帮助我诊断以下错误。我有一个简单的语法:
struct json_start_elem_grammar_object : qi::grammar<StreamIterator,
void(const CharType*, CharType),
ascii::space_type>
{
json_start_elem_grammar_object() : json_start_elem_grammar_object::base_type(start_elem, "start_elem")
{
start_elem = qi::lit('"') > qi::lit(qi::_1) > qi::lit('"') > qi::lit(':') >
qi::lit(qi::_2) > -qi::lit('\n');
}
qi::rule<StreamIterator, void(const CharType*, CharType), ascii::space_type> start_elem;
};
创建此语法的实例时出现错误:
/usr/include/boost/spirit/home/qi/nonterminal/rule.hpp:220:19: required from ‘boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>& boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const Expr&) [with Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::greater, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::greater, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::greater, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::greater, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::greater, 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::vector1<char> > >, 0l>&, const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::lazy_terminal<boost::spirit::tag::lit, boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<boost::spirit::terminal<boost::spirit::tag::lit> >, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >, 1> >, 0l>&>, 2l>&, const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::terminal_ex<boost::spirit::tag::lit, boost::fusion::vector1<char> > >, 0l>&>, 2l>&, const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::terminal_ex<boost::spirit::tag::lit, boost::fusion::vector1<char> > >, 0l>&>, 2l>&, const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::lazy_terminal<boost::spirit::tag::lit, boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<boost::spirit::terminal<boost::spirit::tag::lit> >, boost::spirit::argument<1>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >, 1> >, 0l>&>, 2l>&, const boost::proto::exprns_::expr<boost::proto::tagns_::tag::negate, boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::terminal_ex<boost::spirit::tag::lit, boost::fusion::vector1<char> > >, 0l>&>, 1l>&>, 2l>; Iterator = boost::spirit::basic_istream_iterator<char>; T1 = void(const char*, char); T2 = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]’
/home/marcin/workspace/json_archive/basic_json_grammar.hpp:149:18: required from ‘boost::archive::basic_json_grammar<CharType>::json_start_elem_grammar_object::json_start_elem_grammar_object() [with CharType = char]’
/home/marcin/workspace/json_archive/basic_json_grammar.hpp:194:50: required from ‘boost::archive::basic_json_grammar<CharType>::basic_json_grammar() [with CharType = char]’
/home/marcin/workspace/json_archive/json_iarchive_impl.ipp:141:85: required from ‘boost::archive::json_iarchive_impl<Archive>::json_iarchive_impl(std::istream&, unsigned int) [with Archive = boost::archive::naked_json_iarchive; std::istream = std::basic_istream<char>]’
/home/marcin/workspace/json_archive/json_iarchive.hpp:102:68: required from here
/usr/include/boost/fusion/sequence/intrinsic/size.hpp:33:20: error: no type named ‘size’ in ‘struct boost::spirit::unused_type’
struct unsegmented_size : Sequence::size {};
在哪里
using CharType = char;
using StreamIterator = spirit::basic_istream_iterator<CharType>;
在处理 boost.serialization 和 boost.spirit 编译错误几天后,我完全脑死了,似乎被困在这个问题上:/
这个语法的用法(略简化)是:
json_start_elem_grammar_object start_elem_parser_object;
using invoker = _details::invoke_grammar<CharType, decltype(start_elem_parser_object(name, preamble))>;
invoker::apply( is,
start_elem_parser_object(name, preamble),
"Invalid object element in archive");
在哪里
decltype(is) = IStream&
decltype(name) = const CharType*
decltype(preamble) = CharType
template<typename CharType, typename Expr>
struct invoke_grammar<CharType, Expr> {
using IStream = std::basic_istream<CharType>;
using StreamIterator = spirit::basic_istream_iterator<CharType>;
static void apply(IStream & is, Expr const& grammar, const CharType* errMsg)
{
boost::io::ios_flags_saver ifs(is);
is.unsetf (std::ios::skipws);
StreamIterator it_end;
StreamIterator it_beg (is);
if (!qi::phrase_parse(it_beg, it_end,
grammar,
ascii::space))
{
boost::serialization::throw_exception(
archive_exception(archive_exception::invalid_signature, errMsg)
);
}
}
};
【问题讨论】:
-
我们需要用到这个语法。
-
继承的属性是
qi::_r1、qi::_r2等(不是_1、_2)。另外,请查看qi::symbols<>以避免在此处使用继承的属性。如果你想编写一个语法 control-freak-style 我认为你最好不用 Spirit 来滚动它。 -
@ForEveR 我已经在问题中添加了使用说明
-
@sehe qi::_rX 和 qi::X 在这种情况下会产生相同的编译错误。在选择占位符时,我咨询了 boost-spirit.com/home/2010/03/03/…,从中我了解到 _1 和 _2 在整个解析器的上下文中是可以的 - 如果我错了,请纠正我。我不想使用符号,因为名称和前导码在运行时很晚才知道,并且更容易将它们作为继承属性传递给解析器。谢谢
-
@Marcin 占位符是“好的”,但它们的含义不同(如果你仔细想想,这实际上很有意义)
标签: c++ boost boost-spirit-qi