Haskell:当输入String为空时如何停止Data.Attoparsec.Char8.sepBy?

时间:2010-10-01 07:29:04

标签: parsing haskell attoparsec

我写了以下Haskell代码

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]

我该如何纠正?

感谢回复

2 个答案:

答案 0 :(得分:5)

Partial构造函数并不表示失败,只是如果您希望解析可以继续解析。您应该使用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]

当然,您可能希望最终有一个案例陈述来处理其他案件。

答案 1 :(得分: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] 

(另见this related Stack Overflow question