【问题标题】:parsing n hex digits using attoparsec使用 attoparsec 解析 n 个十六进制数字
【发布时间】:2015-04-22 23:50:52
【问题描述】:

好的,所以我需要解析 n 位十六进制数,但我遇到了一个问题,我无法停止标准 attoparsec 十六进制解析器 hexadecimal

我的第一个想法是这样的:

nHex n = take n *> hexadecimal 但这不起作用,因为它会删除 4 位数字,然后解析字符串 xD 的其余部分

下一个可行的想法是:

hex :: (Num a, Eq a) => Int -> Parser a
hex n = fst . head . readHex <$> count n (satisfy isHexDigit)

但该代码的问题在于 attoparsec 库,它警告不要返回字符列表以考虑速度问题,这个十六进制解析器是我整个程序的基础

尝试提高速度的下一个想法是:

parseFragments :: (Bits a, Integral a) => Int -> Parser a
parseFragments n = do
      fourChars <- B.take n
      let hexDigits = parseOnly hexadecimal fourChars
      case hexDigits of  
              Left err -> fail err
              Right x  -> return x

但是使用 parseOnly 感觉就像是一个可怕的 hack。 有没有更惯用的快速方法?

【问题讨论】:

    标签: haskell attoparsec


    【解决方案1】:

    Data.Attoparsec.ByteString.Char8.hexadecimalimplemented as

    hexadecimal :: (Integral a, Bits a) => Parser a
    hexadecimal = B8.foldl' step 0 `fmap` I.takeWhile1 isHexDigit
      where
        isHexDigit w = (w >= 48 && w <= 57) ||
                       (w >= 97 && w <= 102) ||
                       (w >= 65 && w <= 70)
        step a w | w >= 48 && w <= 57  = (a `shiftL` 4) .|. fromIntegral (w - 48)
                 | w >= 97             = (a `shiftL` 4) .|. fromIntegral (w - 87)
                 | otherwise           = (a `shiftL` 4) .|. fromIntegral (w - 55)
    

    你可以使用几乎相同的,除了你需要检查take的结果,因为你的一些字符可能不是有效的十六进制字符。您可以使用(Maybe a -&gt; Word8 -&gt; Maybe a) 将两者放在同一个函数中,但为简单起见,我使用了上面的函数:

    fixedHexadecimal :: (Integral a, Bits a) => Int -> Parser a
    fixedHexadecimal n = do
        bytes <- A.take n
        if B8.all isHexDigit bytes 
          then B8.foldl' step 0 bytes
          else fail "fixedHexadecimal"
    
      where isHexDigit = -- see above
            step       = -- see above
    

    【讨论】:

      猜你喜欢
      • 2022-11-16
      • 1970-01-01
      • 2010-12-30
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      相关资源
      最近更新 更多