Boost Spirit 实现
这是基于 Boost Spirit (Qi) 的强制实施。为了更好地衡量,包括使用 Boost Spirit (Karma) 进行格式化:
#include <string>
#include <iostream>
#include <fstream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
namespace karma=boost::spirit::karma;
namespace qi =boost::spirit::qi;
static qi::uint_parser<unsigned long long, 16, 16, 16> hex16_p; // parse long hex
static karma::uint_generator<unsigned long long, 16> hex16_f; // format long hex
int main(int argc, char** args)
{
std::ifstream ifs("input.data");
std::string line;
while (std::getline(ifs, line))
{
std::string::iterator begin = line.begin(), end = line.end();
int f0;
std::string f1;
std::vector<unsigned long long> f2;
bool ok = parse(begin, end,
qi::int_ // an integer
>> *qi::alpha // alternatively: *(qi::char_ - '\'')
>> '\'' >> +hex16_p >> '\'' // accepts 'n x 16' hex digits
, f0, f1, f2);
if (ok)
std::cout << "Parsed: " << karma::format(
karma::int_
<< ' ' << karma::string
<< ' ' << ("0x" << hex16_f) % ' '
, f0, f1, f2) << std::endl;
else
std::cerr << "Parse failed: " << line << std::endl;
}
return 0;
}
试运行:
Parsed: 0 ULL 0x4001c0180000000 0xee317bc
Parsed: 52 L 0x4001c0180000000
请参阅下面的调整和示例,了解如何调整的信息,例如十六进制输出
基准测试
我在您提供的样本输入的 100,000 倍上对 @Cubbi's version 和上述书面进行了基准测试。这最初给 Cubbi 的版本带来了一点优势:0.786s 与 0.823s。
现在,这当然是不公平的比较,因为我的代码每次都在动态构建解析器。像这样从循环中取出:
typedef std::string::iterator It;
const static qi::rule<It> parser = qi::int_ >> *qi::alpha >> '\'' >> +hex16_p >> '\'';
bool ok = parse(begin, end, parser, f0, f1, f2);
Boost Spirit 凭借0.093s 赢得了明显的胜利;已经快了 8.5 倍,即使每次迭代仍在构建 karma 格式化程序。
在两个版本中都注释掉了输出格式,Boost Spirit 的速度提高了 11 倍以上
调整、示例
请注意如何轻松调整:
// >> '\'' >> +hex16_p >> '\'' // accepts 'n x 16' hex digits
>> '\'' >> qi::repeat(1,2)[ hex16_p ] >> '\'' // accept 16 or 32 digits
或者像输入一样格式化十六进制输出:
// ("0x" << hex16_f) % ' '
karma::right_align(16, '0')[ karma::upper [ hex16_f ] ] % ""
改变样本输出:
0ULL'04001C0180000000000000000EE317BC'
Parsed: 0 ULL 04001C0180000000000000000EE317BC
52L'04001C0180000000'
Parsed: 52 L 04001C0180000000
HTH