2

I have a parser which parses different data types from an input file. I already figured out, that spirit can decide between short and int, for example:

value %= (shortIntNode | longIntNode);

with

shortIntNode %= (qi::short_ >> !qi::double_)
                [qi::_val = phoenix::bind(&CreateShortIntNode, qi::_1)];
longIntNode  %= (qi::int_ >> !qi::double_)
                [qi::_val = phoenix::bind(&CreateLongIntNode, qi::_1)];

I used this type of rules to detect doubles as well (from the answers here and here). The parser was able to decide between int for numbers > 65535 and short for numbers <= 65535. But, for float_ and double_ it does not work as expected. It just rounds these values to parse it into a float value, if there is a rule like this:

 value %= (floatNode | doubleFloatNode);   

with

floatNode       %= (qi::float_)
                   [qi::_val = phoenix::bind(&CreateFloatNode, qi::_1)];
doubleFloatNode %= (qi::double_)
                   [qi::_val = phoenix::bind(&CreateDoubleFloatNode, qi::_1)];

Do you know if there is something like an option or some other trick to decide between float_ and double_ depending on the data type range?

Thank you very much!

Community
  • 1
  • 1
CppChris
  • 1,226
  • 9
  • 14

1 Answers1

4

Lexing can help. Ultimately you decide, not the parser. Ordering your branches should help. See also

For similar parsers with Boost Spirit.

If you want to decide between float/double, there is no real input criterion. I'd suggest always parsing into double. However, you could, of course use semantic actions to force a float for certain size.

Here's what C++ grammar does (e.g.):

floatrule  = lexeme [ float_ >> 'f' ];
doublerule = double_;

float_or_double = floatrule | doublerule;
Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633