2013-01-11 4 views
13

私はattoparsecのこの動作によって少し混乱しています。障害が発生すると思われる場合、attoparsecを使用して部分結果が表示されるのはなぜですか?

なぜFailを引き起こすために追加文字が必要なのですか?

最初の「x」に遭遇したらすぐに失敗してはいけませんか?

+0

今後の参考として、チケットを開設し、Attoparsecのメンテナーがこのバグを修正しました:https://github.com/bos/attoparsec/issues/97 –

答えて

13

実装の詳細です。stringパーザは、成功する可能性のある入力が十分に残っているかどうかを知る前に終了しません。これらのパーサーの全部または一部の動作の結果です(これは一般的にパフォーマンスには良いと思います)。

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

string sTextlength s単位を取り、その後、sでそれらを比較しようとします。 Textnユニットが利用可能であり、それが見つからない場合

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結果)を求める継続を作成することを確実にする

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最初の試みすぐに十分な入力。

あなたはそれが(そしてensureからdemandInputが、それは失敗します)、それ以上の入力を取得することはできませんことを前もってパーサを語っ

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

と失敗を取得し、以降

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

関連する問題