2013-01-11 13 views
13

Attoparsec'in bu davranışından biraz kafam karıştı.Neden başarısızlık görmeyi beklediğimde attoparsec ile kısmi sonuçlar görüyorum?

$ ghci 
> :m Data.Attoparsec.Text 
> :m + Data.Text 
> parse (string (pack "module")) (pack "mox") 
Partial _ 
> parse (string (pack "module")) (pack "moxxxx") 
Fail "moxxxx" [] "Failed reading: takeWith" 
> 

Fail'i tetiklemek için neden ek karakterlere ihtiyacım var?

olabildiğince kısa birinci "x" karşılaşıldığında olarak Fail gerekmez mi?

+0

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 –

cevap

13

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.

+0

Teşekkürler - bu sizin açıklamanızdan sonra mantıklı. – timbod

İlgili konular