私はattoparsecのこの動作によって少し混乱しています。障害が発生すると思われる場合、attoparsecを使用して部分結果が表示されるのはなぜですか?
なぜFailを引き起こすために追加文字が必要なのですか?
最初の「x」に遭遇したらすぐに失敗してはいけませんか?
私はattoparsecのこの動作によって少し混乱しています。障害が発生すると思われる場合、attoparsecを使用して部分結果が表示されるのはなぜですか?
なぜFailを引き起こすために追加文字が必要なのですか?
最初の「x」に遭遇したらすぐに失敗してはいけませんか?
実装の詳細です。string
パーザは、成功する可能性のある入力が十分に残っているかどうかを知る前に終了しません。これらのパーサーの全部または一部の動作の結果です(これは一般的にパフォーマンスには良いと思います)。
string :: Text -> Parser Text
string s = takeWith (T.length s) (==s)
string s
はText
のlength s
単位を取り、その後、s
でそれらを比較しようとします。 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
結果)を求める継続を作成することを確実にする
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
を与えています。
ありがとうございます。 – timbod
今後の参考として、チケットを開設し、Attoparsecのメンテナーがこのバグを修正しました:https://github.com/bos/attoparsec/issues/97 –