È un dettaglio di implementazione, un parser string
non termina prima di sapere se è disponibile un input sufficiente per il corretto funzionamento. È una conseguenza del comportamento all-or-nothing di questi parser (che, penso, è generalmente buono per le prestazioni).
string :: Text -> Parser Text
string s = takeWith (T.length s) (==s)
string s
cerca di prendere length s
unità di Text
, e poi confrontarli con s
.
takeWith :: Int -> (Text -> Bool) -> Parser Text
takeWith n p = do
s <- ensure n
let h = unsafeTake n s
t = unsafeDrop n s
if p h
then put t >> return h
else fail "takeWith"
takeWith n p
primi cerca di assicurare che n
unità di Text
sono disponibili, e
ensure :: Int -> Parser Text
ensure !n = T.Parser $ \i0 a0 m0 kf ks ->
if lengthAtLeast (unI i0) n
then ks i0 a0 m0 (unI i0)
else runParser (demandInput >> go n) i0 a0 m0 kf ks
where
go n' = T.Parser $ \i0 a0 m0 kf ks ->
if lengthAtLeast (unI i0) n'
then ks i0 a0 m0 (unI i0)
else runParser (demandInput >> go n') i0 a0 m0 kf ks
ensure n
crea una continuazione chiedere più pappa di ingresso (un risultato Partial
) se non trova abbastanza input immediatamente.
È possibile ottenere un fallimento con
Prelude Data.Attoparsec.Text Data.Text> parseOnly (string (pack "module")) (pack "mox")
Left "not enough input"
raccontare il parser fin da subito che non otterrà più di ingresso (allora la demandInput
da ensure
fa fallire), o poi
Prelude Data.Attoparsec.Text Data.Text> parse (string (pack "module")) (pack "mox")
Partial _
Prelude Data.Attoparsec.Text Data.Text> feed it (pack "")
Fail "mox" ["demandInput"] "not enough input"
dicendo al numero Partial
che era, alimentandolo con uno Text
vuoto.
fonte
2013-01-11 23:02:07
Per riferimento futuro, ho aperto un ticket e il responsabile Attoparsec ha corretto questo bug: https://github.com/bos/attoparsec/issues/97 –