metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2011-11-01 12:48 pm
Entry tags:

attoparsec-enumerator, забавное

Три парсера :

--построчный парсер
iterParseLine :: Monad m => E.Iteratee BS.ByteString m BS.ByteString
iterParseLine = iterParser parseLine

--парсер всех строк сразу
iterParseLines :: Monad m => E.Iteratee BS.ByteString m [BS.ByteString]
iterParseLines = iterParser $ many parseLine

--парсер из Enumeratee
enumParseLines :: Monad m => E.Enumeratee BS.ByteString BS.ByteString m b
enumParseLines = E.sequence $ iterParser $ parseLine



и их использование:

parseHandleByLine :: IO.Handle -> IO ()
parseHandleByLine h = loop
      where loop = do s<-E.run_ $ enumHandle1 h E.$$ iterParseLine
                      BS.putStrLn s
                      loop


testIterParseLines :: IO.Handle -> IO ()
testIterParseLines = do
   answers <- E.run_ $ enumHandle1 h E.$$ iterParseLines
   mapM BS.putStrLn answers


testEnumParseLines :: IO.Handle -> IO ()
testEnumParseLines h = E.run_ $ enumHandle1 h E.$= enumParseLines E.$$ printLnI



Второй и третий работают. Первый глючит - пропускает куски потока. Потому как после разбора не сохраняет остаток буфера, прочитанного енумератором и не отдает его при продолжении, а начинает разбор уже со свежепрочитанного буфера.
А нужен именно первый, для того, чтобы посылать по одной команды на девайс и читать и парсить ответы. Т.е. один цикл работы связки enumerator $$ iteratee на каждый ответ от девайса.
Либо использовать не enumerator, а более сложную реализацию - пакет iteratee, который умеет из Iteratee посылать команды обратно в Enumerator, используя исключения и их перехват.
Либо забить и сделать в лоб, т.к. тут на самом деле Iteratees нужны только для сушения мозга и удобства комбинирования парсеров и прочих фильтров потоков.

[identity profile] gds.livejournal.com 2011-11-01 10:17 am (UTC)(link)
чтобы по одной команде -- перед собственно чтением сделать lift io-действия в итерат, и натравить итерат на входной поток. Перед чтением оно выполнит io-действие.