Повысить заданную точку в качестве целочисленного парсера - PullRequest
0 голосов
/ 08 января 2019

У меня есть следующий парсер,

    #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"

Любая помощь очень ценится!

Ответы [ 2 ]

0 голосов
/ 09 января 2019

является следующим лучшим способом, если я хочу сделать 157,47 1574700, умножив 10000?

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 ])
);
0 голосов
/ 09 января 2019

Используйте необязательный синтаксический анализатор, чтобы не дать сбой, если нет дробной части.

Также у вас было 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
...