使用 boost Spirit 解析带有二进制信封的文本文件
Posted
技术标签:
【中文标题】使用 boost Spirit 解析带有二进制信封的文本文件【英文标题】:Parsing text file with binary envelope using boost Spririt 【发布时间】:2015-03-19 12:39:32 【问题描述】:我目前正在尝试为一个 ASCII 文本文件编写一个解析器,该文件被一个带有校验和的小信封包围。
文件的基本结构是:
我想在另一个字符串中提取有效负载以将其提供给 下一个解析器。
我用来解析这个信封的解析器表达式是:
qi::phrase_parse(
first, last,
char_('\x02') >> *print >> char_('\x02') >> *xdigit,
space
);
输入已被消耗...我已经尝试转储负载:
qi::phrase_parse(
first, last,
char_('\x02') >> *print[cout << _1] >> char_('\x02') >> *xdigit,
space
);
但问题是每个换行符、空格等都被省略了!
现在我的问题:
如何提取 0x02/0x03 (ETX/STX) 字节之间的内容 正确地不省略空格、换行符等。
我的方法是先删除信封,然后解析 有效载荷好还是我应该使用其他更好的方法?
【问题讨论】:
【参考方案1】:使用例如qi::seek/qi::confix 帮助您入门(存储库的一部分 http://www.boost.org/doc/libs/1_57_0/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/confix.html)。
但问题是每个换行符、空格等都被省略了!
嗯,那是what a skipper does。不要使用一个,或者:
使用qi::raw[]
要提取中间文本,我建议使用qi::raw
。尽管我不确定您是否真的要将其复制到字符串中(复制听起来很昂贵)。当源是流(或输入迭代器的其他源)时,您可能会这样做。
基本规则:
myrule = '\x02' > raw [ *(char_ - '\x03') ] > '\x03';
您可以添加校验和:
myrule = '\x02' > raw [ *(char_ - '\x03') ] [ _a = _checksum(_1) ] > '\x03' >> qi::word(_a);
假设
qi::locals<uint16_t>
_checksum
是一个合适的 Phoenix 仿函数,它接受一对源迭代器并返回 uint16_t
当然,您可能更喜欢在解析器之外保持校验和。
【讨论】:
非常感谢!到目前为止,我错过了“confix”一章,这对我来说似乎是最好的方法。最后我更喜欢直接将文件解析成程序的数据结构。但是:我可以这样做并同时计算校验和吗?调用两个函子? 没问题。只是,按照我的说明做,不要忘记 %= 分配给规则 好的...谢谢。我会尽量听从你的建议!在我必须编写词法分析器之前,我猜。让我们看看在不问愚蠢问题的情况下我能走多远。 :-) 最后一个问题:使用 boost Qi 和 Spirit.Lex 开发解析器的最佳方法是什么?先从词法分析器开始还是为标记实现解析器? 好吧,如果您要在令牌流上构建解析器,您最好有一个令牌流:) 也就是说,我通常不建议将 Lexer 分离出来。它增加了足够的复杂性来让你的解析器在 Qi 使用的最佳位置上崩溃以上是关于使用 boost Spirit 解析带有二进制信封的文本文件的主要内容,如果未能解决你的问题,请参考以下文章
如何在带有 Boost Spirit 的 AST 中使用只有一个属性的类?