我写了以下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]

但是,由于我已经在上面编写的代码中定义了某些与Somesep的定义,因此我总是得到以下行为:

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]

我该如何纠正?

感谢答复

有帮助吗?

解决方案

Partial 构造函数并不表示失败,仅如果您愿意的话,可以继续解析。您应该服用部分物品并为其提供空的bytestring(根据文档: http://hackage.haskell.org/packages/archive/attoparsec/0.8.1.0/doc/html/data-atta-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]

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

其他提示

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] 

(也可以看看 这个相关的堆栈溢出问题)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top