1

I have some simple code to parse some msg as below,

if (msgtype == BATSAddOrderMsg::longMsgCode)
    m_wire_msg = ( p_ts >> qi::char_(BATSAddOrderMsg::longMsgCode)
                        >> p_orderId
                        >> qi::char_(BATSAddOrderMsg::sideFlag)
                        >> p_shares
                        >> qi::as_string[qi::repeat(6)[qi::char_]]
                        >> m_price
                        >> qi::char_(BATSAddOrderMsg::displayFlag)
                        >> qi::as_string[qi::repeat(4)[qi::char_]] )
                        [qi::_val = phi::construct<BATSAddOrderMsg>(
                                qi::_1, qi::_2, qi::_3, qi::_4, qi::_5, qi::_6, qi::_7, qi::_8, qi::_9)];
else if (msgtype == BATSAddOrderMsg::shortMsgCode)
    m_wire_msg = ( p_ts >> qi::char_(BATSAddOrderMsg::shortMsgCode)
                        >> p_orderId
                        >> qi::char_(BATSAddOrderMsg::sideFlag)
                        >> p_shares
                        >> qi::as_string[qi::repeat(6)[qi::char_]]
                        >> m_price
                        >> qi::char_(BATSAddOrderMsg::displayFlag) )
                        [qi::_val = phi::construct<BATSAddOrderMsg>(
                                qi::_1, qi::_2, qi::_3, qi::_4, qi::_5, qi::_6, qi::_7, qi::_8, "")];

In the above, the long msg type is just the short msg type with one additional field qi::as_string[qi::repeat(4)[qi::char_]]

When I tried to refactor into the below,

auto shared = p_ts >> qi::char_(BATSAddOrderMsg::longMsgCode)
                   >> p_orderId
                   >> qi::char_(BATSAddOrderMsg::sideFlag)
                   >> p_shares
                   >> qi::as_string[qi::repeat(6)[qi::char_]]
                   >> m_price
                   >> qi::char_(BATSAddOrderMsg::displayFlag);
if (msgtype == BATSAddOrderMsg::longMsgCode)
   m_wire_msg = shared >> qi::as_string[qi::repeat(4)[qi::char_]] )
                       [qi::_val = phi::construct<BATSAddOrderMsg>(
                              qi::_1, qi::_2, qi::_3, qi::_4, qi::_5, qi::_6, qi::_7, qi::_8, qi::_9)];

else if (msgtype == BATSAddOrderMsg::shortMsgCode)
    m_wire_msg = shared[qi::_val = phi::construct<BATSAddOrderMsg>(                                
    qi::_1, qi::_2, qi::_3, qi::_4, qi::_5, qi::_6, qi::_7, qi::_8, "")];

The code would compile, but when i run my unittests, it would die with a runtime exception.

Anyone knows why this behavoir from Boost Spirit?

sehe
  • 374,641
  • 47
  • 450
  • 633
Danny
  • 391
  • 2
  • 12

1 Answers1

0

You can't use auto safely with Spirit Parser Expressions. See e.g. boost spirit V2 qi bug associated with optimization level

However, it also looks like

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Cool thanks! it works perfect. For the part about semantic actions being evil, can you give an example of how I should rewrite my example above? – Danny May 28 '18 at 12:04
  • @Danny not without your data types. However I have a zillion examples on the subject: https://stackoverflow.com/search?tab=votes&q=user%3a85371%20semantic%20evil – sehe May 28 '18 at 12:33
  • Let me post some more details in a short while. – Danny Jun 07 '18 at 08:37
  • could you please help take a look here : https://stackoverflow.com/questions/50741125/spirit-grammar-parse-issue – Danny Jun 07 '18 at 12:23