Условный разбор и приведение в Attoparsec - PullRequest
0 голосов
/ 26 октября 2011

Я анализирую двоичный поток с кодировкой длины и пытаюсь скомпилировать этот код. Комбинаторный код (https://github.com/jlouis/combinatorrent/blob/master/src/Protocol/Wire.hs) очень помог мне продвинуться вперед, но теперь я застрял. Как мне использовать frame_length в операторе возврата?

data FrameCont = FINAL | MORE | BADCONT
    deriving (Show, Eq)
frame_cont 0x00      = FINAL
frame_cont 0x01      = MORE
frame_cont otherwise = BADCONT

data FrameSize = Small Word8 | Jumbo B.ByteString
    deriving (Show)

get_fc = do
    raw_cont <- AP.anyWord8
    guard((frame_cont raw_cont) /= BADCONT) AP.<?> "State must be either MORE or FINAL"
    return raw_cont

parser = do
    frame_length <- AP.anyWord8
    case frame_length of
        0x255      ->  return (Jumbo <$> AP.take 8, get_fc, AP.take (fromIntegral frame_length))
        otherwise  ->  return (Small otherwise, get_fc, AP.take (fromIntegral frame_length))

Также: как мне использовать pass (AP.take 8) в Word64?

1 Ответ

1 голос
/ 27 октября 2011

Первые компоненты двух ветвей синтаксического анализатора имеют разные типы, ветвь Jumbo - это Parser FrameSize, другая - простая FrameSize. Если parser должен иметь тип Parser (Parser FrameSize, Parser Word8, Parser ByteString), просто измените первый компонент второй ветви на return (Small otherwise). Однако более вероятно, что вы захотите parser :: Parser (FrameSize, Word8, ByteString), поэтому вам придется запускать другие парсеры внутри parser. Я думаю

parser = do
    frame_length <- AP.anyWord8
    frame_size <- case frame_length of
                    0xFF -> Jumbo <$> AP.take 8   -- 0xFF == 255, 0x255 == 597
                    flen -> return (Small flen)
    fc <- get_fc
    bs <- AP.take (fromIntegral frame_length)
    return (frame_size, fc, bs)

по крайней мере близко к тому, что вы хотите.

Примечание по стилю: вы смешиваете слова camelCase и underscore_separated, лучше соглашайтесь на одно (преобладающим стилем в Haskell является camelCase, поэтому я советую выбирать это).

...