2010-10-01 57 views
3

我已經寫了下面的Haskell代碼Haskell:如何在輸入字符串爲空時停止Data.Attoparsec.Char8.sepBy?

import Data.Attoparsec (Parser) 
import qualified Data.Attoparsec.Char8 as A 
import qualified Data.ByteString.Char8 as B 

someWithSep sep p = A.sepBy p sep 

代碼是假設這種方式工作:

main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89" 
Done "" [123,45,67,89] 

但因爲我在上面寫的代碼定義someWithSep一樣,我總是得到以下行爲:

main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89" 
Partial _ 

,除非我提供了一個損壞的條目:

main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89f" 
Done "f" [123,45,67,89] 

我該如何糾正?

感謝回覆

回答

5

Partial構造並不代表失敗,只是如果你希望它是解析可以繼續。您應該接受部分項目併爲其提供空的ByteString(按照文檔:http://hackage.haskell.org/packages/archive/attoparsec/0.8.1.0/doc/html/Data-Attoparsec-Char8.html#t:Result)以獲得最終結果。

只是爲了顯示它的工作原理:

> let A.Partial f = A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89" in f B.empty 
Done "" [123,45,67,89] 

當然,你可能想在結束了一個case語句來處理其他案件。

+0

附錄:attoparsec中的'feed'函數也可以用來提供空字符串,所以你也可以使用:'A.feed(A.parse(someWithSep A.skipSpace A由Matchi.com提供回到cimal)$ B.pack「123 45 67 89」)B.empty' – 2010-10-01 09:16:42

2

attoparsec接受多個部分的輸入。一個給人的第一片到解析,然後從解析給出結果和所述第二片到飼料,然後給出結果和所述第三片到飼料再次,依此類推。

你喂解析器一個空字符串標記輸入的結束:

A.feed (A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89") B.empty 
Done "" [123,45,67,89] 

或者使用Data.Attoparsec.Lazy,其中懶字符串處理輸入你的結尾:

import qualified Data.Attoparsec.Lazy as L 
import qualified Data.Attoparsec.Char8 as A 
import qualified Data.ByteString.Lazy.Char8 as B 
L.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89" 
Done "" [123,45,67,89] 

相關問題