1. ホーム
  2. haskell

attoparsec または parsec in haskell

2023-09-10 13:50:16

質問

私はいくつかのファイルを解析し、それらをいくつかの定義済みのデータ型に変換する必要があります。

Haskellはそのために2つのパッケージを提供しているようです。

  1. attoparsec
  2. パーセク

この2つの違いは何でしょうか、また、ある規則に従ってテキストファイルを解析するのに適しているのはどちらでしょうか。

どのように解決するのですか?

パーセク

Parsecはquot;user-facing"パーサーに適しています:限られた量の入力があり、エラーメッセージが重要な場合です。非常に速いというわけではありませんが、入力が少なければ問題にはならないでしょう。例えば、私は事実上あらゆるプログラミング言語のツールにParsecを選びます。なぜなら、絶対的に見れば、最大級のソースファイルでも その しかし、エラー メッセージは本当に重要です。

Parsecは様々な入力タイプで動作することができます。つまり、標準的な String や外部レキサーからのトークンのストリームを使うことができます。このため String を使うことができるので、Unicode を完全にうまく処理することができます。 digitletter はUnicode対応です。

Parsecにはモナドトランスフォーマーも付属しており、モナドスタックに重ねることができます。これは、たとえばパース中に追加の状態を追跡したい場合に便利です。また、非決定論的な解析など、よりトリック的な効果を狙うこともできます--モナドトランスフォーマーのいつもの魔法です。

アトパーセク

Attoparsec は Parsec よりもはるかに高速です。大量の入力が予想される場合や、パフォーマンスが本当に重要な場合に使用する必要があります。ネットワーク コード (パケット構造の解析)、大量の生データの解析、バイナリ ファイル形式の処理などに最適です。

Attoparsec は ByteString であり、これは バイナリ のデータです。このため、バイナリファイル形式のようなものを実装するのに適しています。しかし、これはバイナリデータ用なので、テキストエンコーディングのようなものは扱えません。その場合は、attoparsec モジュールを使って Text .

AttoparsecはParsecにはないインクリメンタルなパージングをサポートしています。これは、ネットワークコードのような特定のアプリケーションでは非常に重要ですが、他のアプリケーションでは重要ではありません。

Attorparsec は Parsec よりも悪いエラーメッセージを持ち、パフォーマンスのためにいくつかのハイレベルな機能を犠牲にしています。これは Text または ByteString というように、カスタムレキサーのトークンには使えません。また、モナドトランスフォーマーでもありません。

どれがいい?

最終的に、ParsecとAttoparsecは非常に異なるニッチに対応しています。ハイレベルな違いはパフォーマンスです。パフォーマンスが必要な場合は Attoparsec を選択し、必要でない場合は Parsec を選択します。

私の通常の経験則では、プログラミング言語、設定ファイル形式、ユーザー入力、および正規表現で行うほぼすべてのことに対して、Parsec を選択します。これらは通常、手作業で作成されるため、パーサーはスケールする必要はありませんが、エラーを適切に報告する必要があります。

一方、ネットワークプロトコルの実装、バイナリデータやファイルフォーマットの処理、自動生成された大量のデータの読み込みなどには、Attoparsec を選択します。時間的な制約や大量のデータを扱うような場合、通常は人間が直接書き込まないようなものです。

ご覧のように、選択は実際には非常にシンプルであることが多く、ユースケースはあまり重なりません。ユースケースはあまり重ならないので、どのようなアプリケーションでも、どちらを使うかは明らかです。