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必要に応じて解析を続行できるだけです。部分的なアイテムを取得し、空の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は、複数の部分の入力を受け入れます。1つは解析する最初のピースを与え、次に解析の結果を与え、2番目のピースはフィードし、次にその結果と3番目のピースを再びフィードします。

パーサーに空の文字列を入力して、入力の終わりをマークします。

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] 

この関連するStack Overflowの質問も参照してください)

于 2010-10-01T09:47:08.970 に答える