请帮我诊断以下错误。我有一个简单的语法:
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&amp; 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)
);
}
}
};
答案 0 :(得分:2)
就像我评论的那样,您需要使用qi::_r1
和qi::_r2
,inherited attributes [1] 的占位符。
对于其他人,我可以假设一些事情(因为你的代码不完整而且由于非标准方法而对我有点不清楚):
ascii::blank_type
作为船长,否则lit('\n')
永远不会匹配(除非使用no_skip[]
或lexeme[]
)。您必须注意使用实际的CharType const*
调用解析器,而不是CharType const (&)[]
。后者如果你用例如parser("name", 'a')
。相反,要么
+"name"
我已经做了一个例子并且成功了,看到它 Live on Coliru
完整代码:
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template <typename StreamIterator, typename CharType=char>
struct json_start_elem_grammar_object : qi::grammar<StreamIterator,
void(const CharType*, CharType),
ascii::blank_type>
{
json_start_elem_grammar_object() : json_start_elem_grammar_object::base_type(start_elem, "start_elem")
{
using namespace qi;
_r1_type _name; // prefer descriptive names
_r2_type _preamble;
start_elem =
'"' > lit(_name) > '"' >
':' > lit(_preamble) >
-lit('\n')
;
}
qi::rule<StreamIterator, void(const CharType*, CharType), ascii::blank_type> start_elem;
};
bool doParse(const std::string& input)
{
typedef std::string::const_iterator It;
auto f(begin(input)), l(end(input));
json_start_elem_grammar_object<It> p;
try
{
bool ok = qi::phrase_parse(f, l, p(+"lol", 'q'), ascii::blank);
if (ok)
{
std::cout << "parse success\n";
}
else std::cerr << "parse failed: '" << std::string(f,l) << "'\n";
if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";
return ok;
} catch(const qi::expectation_failure<It>& e)
{
std::string frag(e.first, e.last);
std::cerr << e.what() << "'" << frag << "'\n";
}
return false;
}
int main()
{
bool ok = doParse("\"lol\" : q\n");
return ok? 0 : 255;
}
[1] 另见