web-dev-qa-db-ja.com

haskellのattoparsecまたはparsec

一部のファイルを解析し、それらをいくつかの事前定義されたデータ型に変換する必要があります。

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

  1. attoparsec
  2. parsec

それらの2つの違いは何ですか?いくつかはいくつかのルールに従ってテキストファイルを解析するのにより適していますか?

74
Sibi

パーセク

Parsecは、「ユーザー向け」のパーサーに適しています。入力には制限がありますが、エラーメッセージが重要です。それほど速くはありませんが、入力が小さい場合は問題になりません。たとえば、絶対的な意味で、最大のソースファイルでさえthat大きいわけではないので、エラーメッセージは本当に重要なので、事実上すべてのプログラミング言語ツールにParsecを選択します。

Parsecはさまざまな入力タイプで機能します。つまり、標準のString、またはある種の外部レクサーからのトークンのストリームで使用できます。 Stringを使用できるため、Unicodeを完全に適切に処理します。 digitletterなどの組み込みの基本的なパーサーは、Unicode対応です。

Parsecにはモナド変換器も付属しているため、モナドスタックに重ねることができます。これは、たとえば、解析中に追加の状態を追跡したい場合に役立ちます。また、非決定論的な解析などの奇抜な効果や、モナド変換子の通常の魔法などを利用することもできます。

Attoparsec

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

AttoparsecはbinaryデータであるByteStringsを処理できます。これは、バイナリファイル形式などの実装に適しています。ただし、これはバイナリデータ用であるため、テキストエンコーディングなどは処理しません。そのためには、Textにはattoparsecモジュールを使用する必要があります。

Attoparsecは増分解析をサポートしていますが、Parsecはサポートしていません。これは、ネットワーキングコードなどの特定のアプリケーションにとって非常に重要ですが、他のアプリケーションには関係ありません。

AttorparsecのエラーメッセージはParsecよりも悪く、パフォーマンスのためにいくつかの高レベルの機能を犠牲にしています。 TextまたはByteStringに特化しているため、カスタムレクサーのトークンでは使用できません。また、モナド変換器でもありません。

どれ?

最終的に、ParsecとAttoparsecは非常に異なるニッチに対応します。高レベルの違いはパフォーマンスです。必要な場合は、Attoparsecを選択してください。そうでない場合は、Parsecを使用してください。

私の通常のヒューリスティックは、プログラミング言語、構成ファイルの形式、ユーザー入力、および正規表現で実行するほとんどすべてのものにParsecを選択することです。これらは通常手作業で作成されるため、パーサーはスケーリングする必要はありませんが、エラーを適切に報告する必要があります。

一方、ネットワークプロトコルの実装、バイナリデータとファイル形式の処理、自動生成された大量のデータの読み取りなどには、Attoparsecを選択します。時間の制約や大量のデータを処理しているもので、通常は人間によって直接書き込まれるものではありません。

ご覧のとおり、実際の選択は非常に単純であることが多く、ユースケースはあまり重複していません。おそらく、どのアプリケーションにどれを使用するかはかなり明確になります。

126
Tikhon Jelvis