Haskell: Comment arrêter les données.attoparsec.char8.sepby lorsque la chaîne d'entrée est vide?

StackOverflow https://stackoverflow.com/questions/3837229

  •  27-09-2019
  •  | 
  •  

Question

J'ai écrit le code Haskell suivant

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

Le code est censé fonctionner de cette façon:

main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45  67 89"
Done "" [123,45,67,89]

Mais comme j'ai défini quelque part dans le code écrit ci-dessus, j'obtiens toujours le comportement suivant:

main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45  67 89"
Partial _

À moins que je ne fournisse une entrée corrompue:

main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45  67 89f"
Done "f" [123,45,67,89]

Comment puis-je corriger cela?

Merci de répondre

Était-ce utile?

La solution

La Partial Le constructeur n'indique pas l'échec, simplement que l'analyse pourrait continuer si vous le vouliez. Vous devriez prendre l'article partiel et le nourrir le bytestring vide (selon les documents: http://hackage.haskell.org/packages/archive/attoparsec/0.8.1.0/doc/html/data-attoparsec-char8.html#t:result) pour obtenir le résultat final.

Juste pour le montrer fonctionne:

> 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]

Bien sûr, vous voulez probablement avoir une déclaration de cas à la fin pour gérer les autres cas.

Autres conseils

AtoparsEC accepte la contribution en plusieurs pièces. On donne le premier morceau à analyse, alors donne le résultat de analyse Et le deuxième morceau de nourrir, alors donne ce résultat et la troisième pièce à nourrir encore, et ainsi de suite.

Vous nourrissez l'analyseur une chaîne vide pour marquer la fin de l'entrée:

A.feed (A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45  67 89") B.empty
Done "" [123,45,67,89] 

Ou utilisez data.attoparsec.lazy, où la chaîne paresseuse gère la fin de l'entrée pour vous:

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] 

(Voir également Cette question de débordement de pile connexe)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top