2017-08-24 17 views
2

私はUSB接続からデータを解析して循環バッファに書き込む必要があるプログラムに取り組んでいます。コンジットパーサーが途中で中断されました

私が実行し続ける問題は、パーサが入力を消費していないことです。パーサーコンジットをByteStringのストリームに接続するために別の演算子を使用する必要がありますか?

2つの 'フィルタ' dropCdropWhileCを削除した場合、パーサーは入力の一部を消費しますが、データの最初の数チャンクは迷惑メールであるため失敗します。

明らかに、ライブラリの仕組みに関する私の精神的モデルは、何とかしていません(これまで私はこれまで使ったことはありません)。

空文字列がconduitParserであると、attoparsec自身のparseWithのように、EOFマーカーとして扱われるかどうかも知りたいと思います。

-- | 
sourcePort :: SerialPort -> Producer IO ByteString 
sourcePort port = repeatMC (recv port 16) 


-- | 
parseSerialStream :: (Vector v (Int, Int)) => RingBuffer v (Int, Int) -> SerialPort -> IO() -- ConduitM a c IO() 
parseSerialStream buffer port = sourcePort port 
          .| dropC 4 
          .| dropWhileC B.null 
          .| conduitParser (parseMeasurement <* endOfLine) 
          $$ mapM_C (\item -> print item >> RB.append (snd item) buffer) 
+0

'sourcePort port。 dropC 4 >> dropWhileC B.null >> conduitParser(parseMeasurement <* endOfLine)$$ ..... 'work? – danidiaz

+0

残念ながら、 '' ByteString 'を\ '()''とマッチさせることができませんでした。 – SwiftsNamesake

+1

'' sourcePort port 'のようにかっこではどうでしょう。 (dropC 4 >> dropWhileC B.null >> conduitParser(parseMeasurement <* endOfLine))$$ ..... ' – danidiaz

答えて

2

@ダニジアスはコメントにdropCなどを説明しています。値を指定しないでください。なぜなら、配管(.|)ではなくモナド合成を使用する必要があるからです。

詳細については、this answerを参照してください。

このコードは期待通りに動作します:

parseSerialStream :: RingBuffer VU.Vector (Int, Int) -> SerialPort -> IO() -- ConduitM a c IO() 
parseSerialStream buffer port = sourcePort port 
          .| (dropC 4 
          >> dropWhileC B.null 
          >> conduitParser (parseMeasurement <* endOfLine)) 
          $$ mapM_C (\item -> RB.append (snd item) buffer) 

私はパイプがが見えたか言っています。ああ、よく...

+0

Pinging @MichaelSnoyman – SwiftsNamesake

関連する問題