2017-04-16 1 views
3

私はAttoparsecを使用していますが、これはデフォルトでバックトラックしています。ただし、次の行:Attoparsec解析に失敗しましたが、適切なバックトラッキングではありません。

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

はで失敗します。

Left "not enough input" 

だから、なぜでしょうか? many1 anyCharが3文字(xxx)のみを解析することにした場合、それは成功するはずです。そして、それはバックトラックのためにある時点でそれを行うことを検討するべきでしょうか?

/foo(.*)bar/正規表現Attoparsecを使用して同等の処理を行う適切な方法は何ですか?

答えて

2

私はデフォルトでバックトラックすると言われているAttoparsecを使用しています。

かなりです。 Attoparsec は、バックトラッキングをサポートしていますが、明示的な状況(ドキュメンテーションに記載されている箇所)でのみサポートされています。その目的は、高性能な解析であり、逆行追跡でうまくいきません。

manyTillまたはmanyTill'を探しています。バックトラッキングの動作については、ドキュメントに記載されています。

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

ドキュメントに明示的に「attoparsecパーサーは常に失敗時にバックトラックする」と記載されています。パーサーのコンビネータは完全なバックトラッキングをサポートしていますか?パフォーマンスは私にとって問題ではなく、 'manyTill'を使った提案された解決法は、私のユースケースでうまく動作しません。 –

+3

@IguanaBob [regex-applicative](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であり、実際にバックトラックします。私はあなたが気にかけている本当の財産の実装の詳細である "バックトラッキング"を考えています。 –

関連する問題