3

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

我该如何纠正这个?

感谢回复

4

2 回答 2

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]

当然,您可能希望最后有一个 case 语句来处理其他情况。

于 2010-10-01T09:13:15.293 回答
2

attoparsec 接受多个部分的输入。一个人给第一个片段parse,然后给出parse的结果,第二个片段给feed,然后给出那个结果,第三个片段再次输入,依此类推。

您向解析器提供一个空字符串以标记输入的结束:

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] 

(另见这个相关的堆栈溢出问题

于 2010-10-01T09:47:08.970 回答