使用 boost::spirit 解析二进制文件时更改属性类型

Change attribute type when parsing binary with boost::spirit

本文关键字:属性 类型 boost spirit 使用 二进制文件      更新时间:2023-10-16

我已经成功地使用 boost::spirit::qi 来解析由内置解析器组成的流(例如 byte_little_word等(。但是,我现在需要解析不属于这些类别之一的数据。例如,我想将 16.16 的定点二进制数转换为双精度数;例如,little_word << little_16p16会解析一个uint16_t后跟一个double(从定点数解析(。

我首先考虑了语义操作,但是(我认为...(它们不合适,因为它们不会更改与解析器关联的属性的类型。我也无法弄清楚如何使员工结构解析示例适应这种情况,因为它依赖于 boost::fusion 提供的隐式强制转换。这种方法在这里行不通,因为我显然无法在不引起重大问题的情况下定义从uint32_tdouble的隐式强制转换。

我的倾向是我需要添加非终端来包装内置的二进制原语解析器或从头开始编写终端解析器。即使看了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_ = "x01x02.x01x02";
        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;
    }