C allows hex float literals (of the form 0xffffff.fp0
). These literals, have some uses – for example, they are guaranteed to map to an exact, obvious bit pattern.
However, Rust does not allow such literals. It has decent reasons for doing so (see issue#1433). In particular, they vastly complicate parsing: there is an ambiguity between a hex float literal and a field and/or method off of an integer. This is not, strictly speaking, ambiguous: integers have no fields, and trying to call an integer as a function will be rejected by the type-checker. So one can disambiguate 0xFFFFFFF.Fp3
as being a float if and only if it is not followed by an open parentheses. That, however, is very clumsy, and we really really don’t want to need to do that in the lexer.
A much simpler approach is to require the +
or -
sign in the exponent. 0xFF.Fp-1
is completely unambiguous: since integers have no fields, it will always be rejected by the typechecker, regardless of its context. As such, it is 100% backwards compatible (except to the writers of syntax extensions) to make 0xFF.Fp-1
a single lexeme.
Finally, I propose that the float parsing functions in the stdlib be modified to accept all forms accepted by strtod
. The lexer can reject the ones that are invalid in Rust source trivially.