これは実装の詳細であり、string
パーサーは、成功するために十分な入力が残っているかどうかを知る前に終了しません。これは、これらのパーサーのオールオアナッシング動作の結果です(これは、一般的にパフォーマンスに適していると思います)。
string :: Text -> Parser Text
string s = takeWith (T.length s) (==s)
string s
length s
の単位を取得Text
し、それらを。と比較しようとし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
最初に、n
のユニットText
が使用可能であることを確認しようとします。
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"
パーサーに、これ以上入力を取得しないことを事前に通知します(その後、demandInput
fromensure
は失敗します)、または後で
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
。