C++ 使用boost-Spririt解析具有二进制信封的文本文件

C++ 使用boost-Spririt解析具有二进制信封的文本文件,c++,parsing,boost,boost-spirit,boost-spirit-qi,C++,Parsing,Boost,Boost Spirit,Boost Spirit Qi,我目前正在尝试为ASCII文本文件编写一个解析器,该文件由一个带校验和的小信封包围 文件的基本结构是: 我想提取另一个字符串中的有效负载,将其提供给 下一个解析器 我用来解析此信封的解析器表达式是: qi::phrase_parse( first, last, char_('\x02') >> *print >> char_('\x02') >> *xdigit, space ); 输入已被消耗。。。我已经试着卸下有效载荷: qi::

我目前正在尝试为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
);
qi::短语解析(
首先,最后,,
字符('\x02')>>*打印[cout>char('\x02')>>*xdigit,
空间
);
但问题是,每一个换行符、空格等都被省略了

现在我的问题是:

  • 如何提取0x02/0x03(ETX/STX)字节之间的内容 正确无遗漏空格、换行符等

  • 我的方法是首先移除信封,然后解析 有效载荷很好还是我应该使用另一种更好的方法


  • 例如,使用qi::seek/qi::confix开始(存储库的两个部分)

    但问题是,每一个换行符、空格等都被省略了

    好吧,那就是。不要用一个,或者:

    使用
    qi::raw[]
    要提取中间文本,我建议使用
    qi::raw
    。尽管我不确定您是否真的想将其复制到字符串(复制听起来很昂贵)。您可以在源是流(或其他输入迭代器源)时执行此操作

    开创性规则:

    myrule = '\x02' > raw [ *(char_ - '\x03') ] > '\x03';
    
    您可以添加校验和:

    myrule = '\x02' > raw [ *(char_ - '\x03') ] [ _a = _checksum(_1) ] > '\x03' >> qi::word(_a);
    
    假定

    • qi::本地人
    • \u checksum
      是一个合适的Phoenix函子,它接受一对源迭代器并返回
      uint16\u t

    当然,您可能更喜欢将校验和保留在解析器之外。

    非常感谢!我错过了“confix”一章,这似乎是我最好的方法。最后,我更喜欢直接将文件解析到程序的数据结构中。但是:我可以这样做并同时计算校验和吗?调用两个函子吗?没问题嗯。只是,照我说的做,别忘了%=规则的赋值OK…谢谢。我会尽量按照你的建议做的!在我写lexer之前,我想。让我们看看我能在不再次问愚蠢问题的情况下走多远。:-)最后一个问题:使用boost Qi和Spirit开发解析器的最佳方法是什么。Lex?从首先使用lexer还是为令牌实现解析器?好吧,如果你在令牌流上构建解析器,你最好有一个令牌流:)也就是说,我一般不建议将lexer分离出来。它增加了足够的复杂性,让你的解析器在使用Qi时超过最佳点