在填充到结构体之前解码提取的表达式
Decode extracted expression prior to populating into a struct
我正在尝试创建一个boost::spirit::qi
解析器,它将从'编码'字符串填充结构。字符串的内容是ascii十六进制数据,但我需要提取的字段不一定是按字节对齐的。
我创建了一个简单的例子,我做了类似的事情,提取一个字符串,并从字符串中填充select字符到一个结构体。最终版本需要更复杂的解码,但这里演示了总体思路。
我的解析器。我已经将十六进制字符串解析器绑定到构造结构的语义操作。
template <typename Iterator>
struct MyDataParser : qi::grammar<Iterator, MyData()>
{
static MyData ExtractMyData( const std::vector<char, std::allocator<char> >& val)
{
return MyData(val.at(0), val.at(3), val.at(6));
}
MyDataParser() : MyDataParser::base_type( decode_rule )
{
using namespace qi::labels;
auto data_string = qi::repeat(8)[qi::xdigit];
decode_rule %=
data_string[ boost::phoenix::bind(&ExtractMyData,_1) ]
;
}
qi::rule<Iterator, MyData()> decode_rule;
};
结构体声明。需要两个构造函数来编译。
struct MyData
{
char first_char;
char fourth_char;
char seventh_char;
MyData(char first = 0, char fourth = 0, char seventh = 0)
: first_char(first), fourth_char(fourth), seventh_char(seventh) {}
MyData( const std::vector<char, std::allocator<char> >& val)
: first_char(val.at(0)), fourth_char(val.at(3)), seventh_char(val.at(6)) {}
};
BOOST_FUSION_ADAPT_STRUCT(
MyData,
(char, first_char)
(char, fourth_char)
(char, seventh_char)
)
然而,这看起来有点像一个hack。是否有一个内置的机制来支持qi错误处理?理想情况下,应该直接调用该actor,而不是调用语义操作。
编辑-让我澄清一下我在拍摄什么
他很好地回答了我的问题,但我没有传达全部内容。
1)我想解码一个十六进制字符串使用转换函数。2)使用不耦合到结构体的解析器执行上述操作。
在完美的情况下,我将有一个最终的顶级规则,看起来像这样:
auto rule %= char_
<< int_
<< hex_str_parser
<< repeat(8)[char_]
;
这将填充到一个结构体中,该结构体的定义类似如下:
struct MyData {
char my_char;
int my_int;
unsigned my_hex_value1; // extracted vai hex_str_parser
unsigned my_hex_value2; // extracted vai hex_str_parser
unsigned my_hex_value3; // extracted vai hex_str_parser
std::string my_string;
};
我如何定义一个规则,根据自定义规则从嵌入字符串中提取内容,并无缝地适合另一个解析器?
在我看来,这里并没有使用任何自动属性传播。因此,您可以不使用BOOST_FUSION_ADAPT_*帮助程序¹。
MyData
是一个聚合²,所以如果您不想要它,则不需要该构造函数。MyData{'a', '2', 'e'}
为聚合初始化。
最后,我将使用phoenix::function
来使语义动作更漂亮:
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iostream>
namespace qi = boost::spirit::qi;
struct MyData { char first_char, fourth_char, seventh_char; };
template <typename Iterator>
struct MyDataParser : qi::grammar<Iterator, MyData()>
{
MyDataParser() : MyDataParser::base_type(start)
{
using namespace qi;
start = repeat(8)[xdigit] [_val = _decode(_1)];
}
private:
qi::rule<Iterator, MyData()> start;
struct DecodeF {
MyData operator()(const std::vector<char, std::allocator<char> >& val) const {
return { val.at(0), val.at(3), val.at(6) };
}
};
boost::phoenix::function<DecodeF> _decode;
};
int main() {
std::string const input = "12345678";
MyData data;
if (qi::parse(input.begin(), input.end(), MyDataParser<std::string::const_iterator>(), data))
std::cout << data.first_char << ":" << data.fourth_char << ":" << data.seventh_char << "n";
}
打印
1:4:7
除此之外,他们是老式的。c++ 11允许BOOST_FUSION_ADAPT_STRUCT(MyData, first_char, fourth_char, seventh_char)
²实际上,这里是POD
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么istream不支持右值提取
- 如何设置一个范围来提取我想要获得的信息
- 无法解码base64+deflate数据
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- 视觉工作室项目.提取源文件夹名称
- 使用已使用 java 编码的 openssl 解码数据
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 从字符串中提取整数并形成一个数组
- C ++中的StringStream有助于使用向量从字符串中提取逗号分隔的整数,而不是空格分隔的整数,为什么?
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 从 std::vector<无符号字符>切片中提取 int?
- 在C++中使用重载提取运算符时出现问题
- 在 Qt(C++) 中使用 QProcess 解压缩 - 提取目录问题
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- 错误:(-210:不支持的格式或格式组合)功能'create'中的硬件视频解码器不支持视频源
- 无法从 std::string 中提取C++ Unicode 符号
- 在填充到结构体之前解码提取的表达式