Parsing hexadecimal floats
Opened this issue · 1 comments
gabrielsimoes commented
It seems the parsing utilities in Text.Megaparsec.Char.Lexer
do not support parsing hexadecimal floats out of the box:
0x0.1E
0xA23p-4
0X1.921FB54442D18P
Given how complex these are to parse efficiently and correctly, it seems like it would be a worthy addition to megaparsec.
Let me know if I am missing something obvious and there is an easy way to use the existing functions to parse these.
gabrielsimoes commented
This is what I ended up going with using FloatingHex:
hexfloat = do
zerox <- try $ char '0' >> char' 'x' <&> \x -> "0" ++ [x]
whole <- hexdigits
frac <- option "" $ liftA2 (:) (char '.') hexdigits
exp <- option "p0" $ do
p <- char' 'p'
sign <- optional $ satisfy (\c -> c == '+' || c == '-')
val <- digits
return $ [p] ++ maybe "" (:[]) sign ++ val
let literal = concat [zerox, whole, frac, exp]
case readHFloat literal of
Nothing -> unexpected $ Tokens $ fromList literal
Just f -> return f
digits = T.unpack <$> takeWhile1P (Just "digit") isDigit
hexdigits = T.unpack <$> takeWhile1P (Just "hex digit") isHexDigit
Definitely not the cleanest/most performant, documenting for others who might need it or might be able to suggest improvements.