attoparsec или parsec в haskell

Я должен проанализировать некоторые файлы и преобразовать их в некоторые предопределенные типы данных.

Похоже, что Haskell предоставляет для этого два пакета:

  1. attoparsec
  2. парсек

В чем разница между ними и тем, который лучше подходит для анализа текстового файла по некоторым правилам?

1 ответ

Решение

парсек

Parsec хорош для парсеров, ориентированных на пользователя: вещи, в которых количество ввода ограничено, но сообщения об ошибках имеют значение. Это не очень быстро, но если у вас небольшие входные данные, это не должно иметь значения. Например, я бы выбрал Parsec практически для любых инструментов языка программирования, поскольку - в абсолютном выражении - даже самые большие исходные файлы не такие большие, но сообщения об ошибках действительно имеют значение.

Parsec может работать на разных типах ввода, что означает, что вы можете использовать его со стандартным String или с потоком токенов от какого-то внешнего лексера. Так как он может использовать String, он прекрасно работает с Unicode; встроенные базовые парсеры вроде digit а также letter Unicode-осведомлен.

Parsec также поставляется с преобразователем монад, что означает, что вы можете наложить его в стек монад. Это может быть полезно, например, если вы хотите отслеживать дополнительное состояние во время анализа. Вы могли бы также пойти на более триповые эффекты, такие как недетерминированный анализ или что-то в этом роде - обычное волшебство монадных преобразователей.

Attoparsec

Аттопарсек намного быстрее чем парсек. Вы должны использовать его, когда ожидаете получить большое количество входных данных или производительность действительно имеет значение. Он отлично подходит для таких вещей, как сетевой код (синтаксический анализ структуры пакетов), анализ больших объемов необработанных данных или работа с двоичными форматами файлов.

Аттопарсек может работать с ByteString с, которые являются двоичными данными. Это делает его хорошим выбором для реализации таких вещей, как двоичные форматы файлов. Однако, поскольку это для двоичных данных, оно не обрабатывает такие вещи, как кодирование текста; для этого вы должны использовать модуль attoparsec для Text,

Attoparsec поддерживает инкрементный разбор, а Parsec - нет. Это очень важно для некоторых приложений, таких как сетевой код, но не имеет значения для других.

Attorparsec имеет худшие сообщения об ошибках, чем Parsec, и жертвует некоторыми высокоуровневыми функциями для повышения производительности. Специализируется на Text или же ByteString, так что вы не можете использовать его с токенами из пользовательского лексера. Это также не монадный трансформатор.

Который из?

В конечном счете, Parsec и Attoparsec обслуживают самые разные ниши. Разница в высоком уровне - это производительность: если вам это нужно, выберите Attoparsec; если нет, просто иди с Парсек.

Моя обычная эвристика - это выбор Parsec для языков программирования, форматов файлов конфигурации и ввода данных пользователем, а также практически для всего, что я в противном случае сделал бы с регулярным выражением. Эти вещи обычно создаются вручную, поэтому анализаторы не нуждаются в масштабировании, но они должны хорошо сообщать об ошибках.

С другой стороны, я бы выбрал Attoparsec для таких вещей, как реализация сетевых протоколов, работа с двоичными данными и форматами файлов или чтение больших объемов автоматически сгенерированных данных. Вещи, где вы имеете дело с временными ограничениями или большими объемами данных, которые обычно не написаны непосредственно человеком.

Как видите, выбор на самом деле часто довольно прост: варианты использования не сильно перекрываются. Скорее всего, будет довольно ясно, какой из них использовать для любого конкретного приложения.

Другие вопросы по тегам