-- | Parse a JSON number.
scientific :: Parser Scientific
scientific = do
sign <- A.peekWord8'
let !positive = not (sign == W8_MINUS)
when (sign == W8_PLUS || sign == W8_MINUS) $
void A.anyWord8
n <- decimal0
let f fracDigits = SP (B.foldl' step n fracDigits)
(negate $ B.length fracDigits)
step a w = a * 10 + fromIntegral (w - W8_0)
dotty <- A.peekWord8
SP c e <- case dotty of
Just W8_DOT -> A.anyWord8 *> (f <$> A.takeWhile1 isDigit_w8)
_ -> pure (SP n 0)
let !signedCoeff | positive = c
| otherwise = -c
(A.satisfy (\ex -> case ex of W8_e -> True; W8_E -> True; _ -> False) *>
fmap (Sci.scientific signedCoeff . (e +)) (signed decimal)) <|>
return (Sci.scientific signedCoeff e)
{-# INLINE scientific #-}
主要要修改的是decimal0部分,它捕获一个零或多个十进制数的序列。
import qualified Data.ByteString as B
decimal0' :: Parser Integer
decimal0' = do
digits <- B.filter (\x -> x /= 44) <$> A.takeWhile1 (\x -> isDigit_w8 x || x == 44)
if B.length digits > 1 && B.unsafeHead digits == 48
then fail "leading zero"
else return (bsToInteger digits)
然后使用具有以下内容的一个:
import qualified Data.Attoparsec.ByteString as A
import qualified Data.Scientific as Sci
import Data.Attoparsec.ByteString.Char8 (isDigit_w8)
-- | Parse a JSON number.
scientific :: Parser Scientific
scientific = do
sign <- A.peekWord8'
let !positive = not (sign == 45)
when (sign == 43 || sign == 45) $
void A.anyWord8
n <- decimal0'
let f fracDigits = SP (B.foldl' step n fracDigits)
(negate $ B.length fracDigits)
step a w = a * 10 + fromIntegral (w - W8_0)
dotty <- A.peekWord8
SP c e <- case dotty of
Just 46 -> A.anyWord8 *> (f <$> A.takeWhile1 isDigit_w8)
_ -> pure (SP n 0)
let !signedCoeff | positive = c
| otherwise = -c
(A.satisfy (\ex -> case ex of W8_e -> True; W8_E -> True; _ -> False) *>
fmap (Sci.scientific signedCoeff . (e +)) (signed decimal)) <|>
return (Sci.scientific signedCoeff e)
{-# INLINE scientific' #-}
2条答案
按热度按时间kognpnkq1#
如果解析器的其余部分没有逗号,一个便宜而令人愉快的解决方案是在解析之前将它们全部删除。
如果确实需要在解析过程中保留逗号,那么最好的办法是查找
scientific
的源代码,然后进行复制、粘贴和调整--我不知道有什么预先制作的解析器可以接受逗号。cygmwpex2#
不解析的原因是
scientific
类型主要是为JSON解析定义的,而JSON不允许这样做,并且使用逗号分隔数组和对象中的元素。我们可以看看
scientific
[src]的实现:主要要修改的是
decimal0
部分,它捕获一个零或多个十进制数的序列。然后使用具有以下内容的一个:
这没有考虑到逗号被放置在每三个数字之后,因此这将需要额外的逻辑,但是这是在
Scientific
的整数部分中工作接受逗号的基本实现。