Mic*_*val 8 c++ binary parsing boost-spirit boost-spirit-qi
我已经成功地使用boost::spirit::qi到解析由内置的解析器(如流byte_,little_word等).但是,我现在需要解析不完全属于这些类别之一的数据.例如,我想将16.16定点二进制数转换为double; 例如,little_word << little_16p16将解析a uint16_t后跟a double(从定点数解析).
我首先考虑语义动作,但(我认为......)它们不合适,因为它们不会更改与解析器关联的属性的类型.我也无法弄清楚如何使员工struct-parsing示例适应这种情况,因为它依赖于提供的隐式转换boost::fusion.这种方法在这里不起作用,因为我显然不能uint32_t在double不引起重大问题的情况下定义隐式转换.
我倾向于我需要添加非终端来包装内置的二进制原语解析器或从头开始编写终端解析器.即使看了之后qi_binary.hpp,我也不知道该如何做.任何人都可以提供一些示例代码和/或指导我开始相关的参考资料吗?
template < typename Iterator >
struct parser : boost::spirit::qi::grammar < Iterator, double(), boost::spirit::ascii::space_type >
{
struct cast_impl
{
template < typename A >
struct result { typedef double type; };
double operator()(boost::fusion::vector < boost::uint16_t, boost::uint16_t > arg) const
{
// cast here
return 0;
}
};
parser() : parser::base_type(main)
{
pair = boost::spirit::qi::little_word >> '.' >> boost::spirit::qi::little_word;
main = pair[boost::spirit::qi::_val = cast(boost::spirit::qi::_1)];
}
boost::spirit::qi::rule < Iterator, boost::fusion::vector < boost::uint16_t, boost::uint16_t > (), boost::spirit::ascii::space_type > pair;
boost::spirit::qi::rule < Iterator, double(), boost::spirit::ascii::space_type > main;
boost::phoenix::function<cast_impl> cast;
};
int _tmain(int argc, _TCHAR* argv[])
{
typedef std::string container;
container data_ = "\x01\x02.\x01\x02";
container::iterator iterator_ = data_.begin();
double value_;
bool result_ =
boost::spirit::qi::phrase_parse(iterator_, data_.end(),
parser < container::iterator > (),
boost::spirit::ascii::space,
value_);
return 0;
}
Run Code Online (Sandbox Code Playgroud)