Bir uygulama detayı, bir string
çözümleyicinin, başarılı olması için yeterli girdi olup olmadığını bilmeden bitmez. Bu ayrıştırıcıların tamamen ya da hiç olmayan davranışlarının bir sonucudur (ki bence genel olarak performans için iyidir).
string :: Text -> Parser Text
string s = takeWith (T.length s) (==s)
string s
Text
ait
length s
birimlerini almak ve sonra
s
ile karşılaştırılması çalışır.
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
ilk çalışır Text
ait n
birimleri kullanılabilir olduğundan emin olmak için, ve
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
o bulamazsa, (a Partial
sonuç) daha batağı girişi soran devamını oluşturur Hemen yeterli giriş.
Sen
Prelude Data.Attoparsec.Text Data.Text> parseOnly (string (pack "module")) (pack "mox")
Left "not enough input"
buna o kadar girdi (o ensure
den demandInput
başarısız yapar) olsun, ya da daha sonra
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"
olmaz ön ayrıştırıcı anlatan bir başarısızlık alabilirsiniz
, Partial
sonucunu söyleyerek, bunun boş bir Text
beslemesiydi.
Gelecekte başvurmak için bir bilet açtım ve Attoparsec sürdüren kişi bu hatayı düzeltti: https://github.com/bos/attoparsec/issues/97 –