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!
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;