Search code examples
c++parsingc++14boost-spiritboost-spirit-x3

boost spirit x3 int32 | double_ fails to parse double


I am trying to write a parser, which parses either a int32_t or a double. As a first try I wrote this parser:

const auto int_or_double = boost::spirit::x3::int32 | boost::spirit::x3::double_;

which I expect to get back a boost::variant<int32_t, double> the parser succeed to parse ints like 12, 100, -42, 7 but it fails to parse doubles like 13.243, 42.7, 12.0 -10000.3

here is a live demo

Why does this parser fail on doubles?


Solution

  • Your problem is very similar to this question.

    When the integer parser occurs first in your grammar, it is preferred. For the input "12.9" the parser will parse the integer part of "12.9 which is 12 and will stop at the .. live example

    You have to reverse the order so the double parser is preferred over the integer one:

    const auto double_or_int =  boost::spirit::x3::double_ | boost::spirit::x3::int32;
    

    This will now work for "12.9": live example

    However, since a double parser also parses an integer, you will always get a double, even if the input is "12": live example

    In order to prevent this, you need a strict double parser:

    boost::spirit::x3::real_parser<double, boost::spirit::x3::strict_real_policies<double> > const double_ = {};
    

    live example