attoparsec или парсек в Haskell
Мне нужно разобрать некоторые файлы и конвертировать их в некоторые предопределенные типы данных.
Haskell, кажется, предоставляет два пакета для этого:
в чем разница между ними и какой из них лучше подходит для парсинга текстового файла по определенным правилам?
1 ответ:
Parsec
Parsec хорош для" пользовательских " парсеров: вещи, где у вас есть ограниченное количество входных данных, но сообщения об ошибках имеют значение. Это не очень быстро, но если у вас есть небольшие входы, это не должно иметь значения. Например, я бы выбрал Parsec практически для любых инструментов языка программирования, так как-в абсолютном выражении-даже самые большие исходные файлы не это большие, но сообщения об ошибках действительно имеют значение.
парсек может работать на различных типах входного сигнала, что означает, что вы можете использовать его со стандартным
Stringили с потоком токенов из внешнего лексера какого-то типа. Так как он может использоватьString, Он отлично обрабатывает Unicode для вас; встроенные базовые Парсеры, такие какdigitиletterявляются Unicode-aware.Parsec также поставляется с трансформатором монад, что означает, что вы можете разместить его в стеке монад. Это может быть полезно, если вы хотите отслеживать дополнительное состояние во время анализа, например. Вы также можете пойти на большее Триппи-эффекты, такие как недетерминированный разбор или что-то еще-обычная магия трансформаторов монад.
Attoparsec
Attoparsec намного быстрее, чем Parsec. Вы должны использовать его, когда вы ожидаете получить большие объемы ввода или производительности действительно имеет значение. Он отлично подходит для таких вещей, как сетевой код (разбор структуры пакетов), разбор больших объемов необработанных данных или работа с двоичными форматами файлов.
Attoparsec может работать с
ByteStrings, которые являются binary данные. Это делает его хорошим выбором для реализации таких вещей, как бинарные форматы файлов. Однако, поскольку это для двоичных данных, он не обрабатывает такие вещи, как кодирование текста; для этого вы должны использовать модуль attoparsec дляText.Attoparsec поддерживает инкрементный синтаксический анализ, который Parsec не делает. Это очень важно для некоторых приложений, таких как сетевой код, но не имеет значения для других.
Attorparsec имеет худшую ошибку сообщения, чем парсек и жертвует некоторые функции высокого уровня для производительности. Он специализируется на
TextилиByteString, поэтому вы не можете использовать его с токенами из пользовательского лексера. Это также не трансформатор монады.Который Из Них?
в конечном счете, парсек и Attoparsec удовлетворить очень разные ниши. Разница в высоком уровне-это производительность: если вам это нужно, выберите Attoparsec; если нет, просто перейдите на Parsec.
моя обычная эвристика-это выбор парсека для языки программирования, форматы файлов конфигурации и пользовательский ввод, а также почти все, что я в противном случае сделал бы с регулярным выражением. Эти вещи обычно производятся вручную, поэтому парсерам не нужно масштабировать, но им нужно хорошо сообщать об ошибках.
С другой стороны, я бы выбрал Attoparsec для таких вещей, как реализация сетевых протоколов, работа с двоичными данными и форматами файлов или чтение больших объемов автоматически генерируемых данных. Вещи, где вы имеете дело со временем ограничения или большие объемы данных, которые обычно не записываются непосредственно человеком.
как вы видите, выбор на самом деле часто довольно прост: варианты использования не перекрываются очень много. Скорее всего, это будет довольно ясно, какой из них использовать для любого данного приложения.
Comments