为什么我看到attoparsec部分结果时,我希望看到失败?(Why do I see Partia

2019-08-06 13:11发布

我对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”失败?

Answer 1:

这是一个实现细节,一个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 np第一次尝试,以确保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"

告诉解析器前面,它不会得到任何更多的输入(当时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



文章来源: Why do I see Partial results with attoparsec when I expect to see Failure?