Haskell: come interrompere i dati.attoparec.char8.sepby Quando la stringa di input è vuota?
-
27-09-2019 - |
Domanda
Ho scritto il seguente codice 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
Si suppone che il codice funzioni in questo modo:
main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89"
Done "" [123,45,67,89]
Ma da quando ho definito un po 'come nel codice scritto sopra, ottengo sempre il seguente comportamento:
main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89"
Partial _
A meno che non fornisca una voce corrotta:
main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89f"
Done "f" [123,45,67,89]
Come posso correggerlo?
Grazie a risposta
Soluzione
Il Partial
Il costruttore non indica un fallimento, semplicemente che l'analisi potrebbe continuare se lo desideri. Dovresti prendere l'oggetto parziale e dargli da mangiare il bytestring vuoto (secondo i documenti: http://hackage.haskell.org/packages/archive/attoparsec/0.8.1.0/doc/html/data-attoparsec-char8.html#t:result) per ottenere il risultato finale.
Solo per dimostrare che funziona:
> 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]
Naturalmente, probabilmente vuoi avere una dichiarazione del caso alla fine per gestire gli altri casi.
Altri suggerimenti
Attoparsec accetta l'input in più pezzi. Si dà il primo pezzo a analizzare, Quindi dà il risultato da analizzare e il secondo pezzo a alimentazione, Quindi dà quel risultato e il terzo pezzo a alimentazione Ancora una volta, e così via.
Si alimenta al parser una stringa vuota per contrassegnare la fine dell'input:
A.feed (A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89") B.empty
Done "" [123,45,67,89]
Oppure usa data.attopArsec.lazy, in cui la stringa pigra gestisce la fine dell'input per te:
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]
(Guarda anche Questa domanda di overflow dello stack correlata)