2017-04-16 64 views
3

我使用Attoparsec據說這是在默認情況下原路返回。但是,下面的一行:Attoparsec解析失敗,但不應該用適當的回溯

parseOnly (string "foo" *> many1 anyChar <* string "bar") "fooxxxbar" 

失敗:

Left "not enough input" 

爲什麼會這樣呢?如果many1 anyChar決定只解析三個字符(xxx),它應該是成功的。它應該考慮在某個時候這樣做,因爲回溯,不是嗎?

什麼是做相當於使用Attoparsec /foo(.*)bar/正則表達式的正確方法?

回答

2

我使用Attoparsec據說這是在默認情況下原路返回。

不太。 Attoparsec 確實支持回溯,但只有在一些明確的情況下(在文件說起來)。它的目的是高性能的解析,並且不出所料,它不能很好地跟蹤回溯。

您正在尋找manyTillmanyTill'。請注意,文檔中提到了回溯行爲。

ghci> manyTill1 p e = (:) <$> p <*> manyTill p e 
ghci> parseOnly (string "foo" *> manyTill1 anyChar (string "bar")) "fooxxxbar" 
Right "xxx" 
+1

那麼,該文檔明確指出:「attoparsec解析器總是失敗回溯」。什麼解析器組合器在那裏有完整的回溯支持?性能對我來說不是問題,用'manyTill'提出的解決方案對我的用例來說效果不好。 –

+3

@IguanaBob [正則表達式,應用性(http://hackage.haskell.org/package/regex-applicative)不會回溯,卻總是成功的,如果它是可能的。 [READP](http://hackage.haskell.org/package/base-4.9.1.0/docs/Text-ParserCombinators-ReadP.html)具有相同的屬性,並且可以解析多個語法。 [ReadS](http://hackage.haskell.org/package/base-4.9.1.0/docs/Text-ParserCombinators-ReadP.html#t:ReadS)基本上效率較低的ReadP,並且實際上會回溯 - 但我認爲「回溯」是您關心的房地產的實施細節,三者都滿足。 –