Boost spirit不动点作为整数解析器
Boost spirit fixed point as integer parser
我有以下解析器,
#define PRICE_MULT 10000
qi::uint_parser<uint32_t, 10, 1, 6> int_part;
qi::uint_parser<uint32_t, 10, 1, 6> dec_part;
qi::rule<Iterator, uint64_t()> fixed_point =
(int_part >> "." >> dec_part )[qi::_val = qi::_1 * PRICE_MULT + qi::_2];
m_wire_msg = ( qi::as_string[*qi::alpha] >> "," // symbol
>> qi::ulong_long >> "," // symbol seq num
>> qi::ulong_long >> "," // order id
>> (fixed_point | qi::ulong_) >> ","
>> qi::uint_ >> "," // volume
>> qi::char_ >> "," // side
>> +qi::space >> "," // firm id
>> qi::ushort_ // parity split
但是解析失败,
"AAPL,1192544,16044086616349464,157.47,100,S, ,0"
具体来说,157.47 有时可以是整数,例如。 157 本身,这就是我使用“(fixed_point | qi::ulong_)”的原因。
但是解析失败,我不是很明白。理想情况下也应该正确解析以下内容,
"AAPL,1192544,16044086616349464,157,100,S, ,0"
非常感谢任何帮助!
如果没有小数部分,使用可选的解析器不会失败。
另外,您的 PRICE_MULT
有 4 个零,但 dec_part
最多允许 6 位数字。
#define PRICE_MULT 10000
qi::uint_parser<std::uint32_t, 10, 1, 6> int_part;
qi::uint_parser<std::uint32_t, 10, 1, 4> dec_part;
qi::rule<Iterator, std::uint64_t()> fixed_point =
int_part[qi::_val = qi::_1 * PRICE_MULT]
>> -('.' >> dec_part[qi::_val += qi::_1]);
https://wandbox.org/permlink/H46ujDgJ57gyE69I
正确的定点解析器可能如下所示:
constexpr std::uint64_t lut[] = { 1, 10, 100, 1000, 10000, 100000, 1000000 };
constexpr int frac_digits = 6;
qi::uint_parser<std::uint32_t, 10, 1, 6> const int_part;
qi::uint_parser<std::uint32_t, 10, 1, frac_digits> const dec_part;
qi::rule<Iterator, std::uint64_t()> fixed_point
= int_part[qi::_val = qi::_1 * lut[frac_digits]] // parse integer part and save multiplied by lut[frac_digits]
>> ( !qi::lit('.') // do not fail on missing fractional part
| ('.' >> qir::iter_pos >> dec_part >> qir::iter_pos)[ // parse fraction and save/syntesize iterators before and after
qi::_val += qi::_2 * phx::ref(lut)[ // multiple fraction by lookuped pow10 value
frac_digits - (qi::_3 - qi::_1)]]
>> *qi::digit); // consume unparsed digits
https://wandbox.org/permlink/mtdMDPzB2RjPxQlD
input result
===== ======
123 123000000
123.0 123000000
123.4 123400000
123.45 123450000
123.456 123456000
123.4567 123456700
123.45678 123456780
123.456789 123456789
123.456789123 123456789
123. fail
.123 fail
如果我想通过乘以 10000 使 157.47 成为 1574700,以下是最好的方法吗?
m_fixed_point = m_int_part[qi::_val = qi::_1 * PRICE_MULT] >>
-("." >> -(m_digit[qi::_val += qi::_1 * 1000])
>> -(m_digit[qi::_val += qi::_1 * 100])
>> -(m_digit[qi::_val += qi::_1 * 10])
>> -(m_digit[qi::_val += qi::_1 ])
);
我有以下解析器,
#define PRICE_MULT 10000
qi::uint_parser<uint32_t, 10, 1, 6> int_part;
qi::uint_parser<uint32_t, 10, 1, 6> dec_part;
qi::rule<Iterator, uint64_t()> fixed_point =
(int_part >> "." >> dec_part )[qi::_val = qi::_1 * PRICE_MULT + qi::_2];
m_wire_msg = ( qi::as_string[*qi::alpha] >> "," // symbol
>> qi::ulong_long >> "," // symbol seq num
>> qi::ulong_long >> "," // order id
>> (fixed_point | qi::ulong_) >> ","
>> qi::uint_ >> "," // volume
>> qi::char_ >> "," // side
>> +qi::space >> "," // firm id
>> qi::ushort_ // parity split
但是解析失败,
"AAPL,1192544,16044086616349464,157.47,100,S, ,0"
具体来说,157.47 有时可以是整数,例如。 157 本身,这就是我使用“(fixed_point | qi::ulong_)”的原因。
但是解析失败,我不是很明白。理想情况下也应该正确解析以下内容,
"AAPL,1192544,16044086616349464,157,100,S, ,0"
非常感谢任何帮助!
如果没有小数部分,使用可选的解析器不会失败。
另外,您的 PRICE_MULT
有 4 个零,但 dec_part
最多允许 6 位数字。
#define PRICE_MULT 10000
qi::uint_parser<std::uint32_t, 10, 1, 6> int_part;
qi::uint_parser<std::uint32_t, 10, 1, 4> dec_part;
qi::rule<Iterator, std::uint64_t()> fixed_point =
int_part[qi::_val = qi::_1 * PRICE_MULT]
>> -('.' >> dec_part[qi::_val += qi::_1]);
https://wandbox.org/permlink/H46ujDgJ57gyE69I
正确的定点解析器可能如下所示:
constexpr std::uint64_t lut[] = { 1, 10, 100, 1000, 10000, 100000, 1000000 };
constexpr int frac_digits = 6;
qi::uint_parser<std::uint32_t, 10, 1, 6> const int_part;
qi::uint_parser<std::uint32_t, 10, 1, frac_digits> const dec_part;
qi::rule<Iterator, std::uint64_t()> fixed_point
= int_part[qi::_val = qi::_1 * lut[frac_digits]] // parse integer part and save multiplied by lut[frac_digits]
>> ( !qi::lit('.') // do not fail on missing fractional part
| ('.' >> qir::iter_pos >> dec_part >> qir::iter_pos)[ // parse fraction and save/syntesize iterators before and after
qi::_val += qi::_2 * phx::ref(lut)[ // multiple fraction by lookuped pow10 value
frac_digits - (qi::_3 - qi::_1)]]
>> *qi::digit); // consume unparsed digits
https://wandbox.org/permlink/mtdMDPzB2RjPxQlD
input result
===== ======
123 123000000
123.0 123000000
123.4 123400000
123.45 123450000
123.456 123456000
123.4567 123456700
123.45678 123456780
123.456789 123456789
123.456789123 123456789
123. fail
.123 fail
如果我想通过乘以 10000 使 157.47 成为 1574700,以下是最好的方法吗?
m_fixed_point = m_int_part[qi::_val = qi::_1 * PRICE_MULT] >>
-("." >> -(m_digit[qi::_val += qi::_1 * 1000])
>> -(m_digit[qi::_val += qi::_1 * 100])
>> -(m_digit[qi::_val += qi::_1 * 10])
>> -(m_digit[qi::_val += qi::_1 ])
);