2013-01-11 15 views
13

मैं attoparsec के इस व्यवहार से थोड़ा उलझन में हूँ।जब मैं विफलता देखने की उम्मीद करता हूं तो मुझे अटॉर्सेसेक के साथ आंशिक परिणाम क्यों दिखाई देते हैं?

$ 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" 
> 

मुझे विफलता को ट्रिगर करने के लिए अतिरिक्त वर्णों की आवश्यकता क्यों है?

क्या यह पहले "x" के रूप में जल्द ही विफल नहीं होना चाहिए?

+0

भविष्य के संदर्भ के लिए, मैंने एक टिकट खोला और Attoparsec रखरखावकर्ता ने इस बग को ठीक किया: https://github.com/bos/attoparsec/issues/97 –

उत्तर

13

यह एक कार्यान्वयन विस्तार है, string पार्सर यह नहीं जानता कि इससे पहले कि संभवतः सफल होने के लिए पर्याप्त इनपुट शेष है या नहीं। यह इन पार्सर्स के सभी या कुछ भी व्यवहार का नतीजा नहीं है (जो, मुझे लगता है, आमतौर पर प्रदर्शन के लिए अच्छा है)।

string :: Text -> Parser Text 
string s = takeWith (T.length s) (==s) 

string sText की length s इकाइयों ले, और फिर उन्हें 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 पहले की कोशिश करता सुनिश्चित करना है कि Text की n इकाइयों उपलब्ध हैं, और

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 (एक Partial परिणाम) अधिक दलिया इनपुट के लिए पूछ रहा है, तो यह नहीं मिल रहा है एक निरंतरता बनाता है पर्याप्त इनपुट तुरंत।

आप

Prelude Data.Attoparsec.Text Data.Text> parseOnly (string (pack "module")) (pack "mox") 
Left "not enough input" 

सामने पार्सर कह कि यह किसी भी अधिक इनपुट (तब demandInputensure से इसे विफल करता है) नहीं मिलेगा, या बाद में

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" 
के साथ एक विफलता प्राप्त कर सकते हैं

Partial बताकर परिणाम यह था कि यह एक खाली Text खिला रहा था।

+0

धन्यवाद - यह आपके स्पष्टीकरण के बाद समझ में आता है। – timbod

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^