Подтвердить что ты не робот

Есть ли в F # известная библиотека комбинаторных парсеров, которая может анализировать двоичные (а не текстовые) файлы?

Я знаком с некоторыми из основ fparsec, но он, похоже, ориентирован на текстовые файлы или потоки.

Есть ли другая библиотека F #, которая может эффективно анализировать двоичные файлы? Или fparsec может быть легко модифицирован для эффективной работы с бинарными потоками?

4b9b3361

Ответ 1

Вас могут заинтересовать комбинаторы сортировщиков. Они немного похожи на комбинаторы парсеров, но более ориентированы на более простые двоичные форматы (picklers позволяют создавать двоичные данные, а разборщики анализируют их). Существует вполне читаемая статья об идее (PDF) Эндрю Кеннеди (автор единиц измерения).

У меня не так много опыта с ними, но я просто понял, что это может быть актуально для вас. Идея используется в компиляторе F # для генерации некоторых двоичных ресурсов (например, котировок, хранящихся в ресурсах). Хотя, я не уверен, что реализация F # компилятора хороша (это одна из тех вещей, с ранних дней компилятора F #).

Ответ 2

Проблема с работой с бинарными потоками не является проблемой парсера сама по себе, это проблема лексинга. Лексер - это то, что превращает необработанные данные в элементы, которые может обрабатывать синтаксический анализ.

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

Проблема, однако, в том, что большинство систем синтаксического анализа и лексинга сегодня сами создаются с помощью инструмента более высокого уровня. И этот инструмент, скорее всего, не предназначен для работы с бинарными потоками. То есть, нецелесообразно указывать маркеры и грамматику двоичного потока, который можно использовать для создания последующих парсеров и лексера. Кроме того, вероятно, нет никакой поддержки для концепций более высокого уровня многобайтовых двоичных чисел (шорты, длинные, плавающие и т.д.), С которыми вы, вероятно, столкнетесь в двоичном потоке, а также для того, чтобы сгенерированный парсер мог хорошо работать с ними если вам действительно нужно работать с их фактическим значением, опять же потому, что системы в основном предназначены для текстовых токенов, а базовая среда выполнения обрабатывает детали преобразования этого текста, что-то, что может использовать машина (например, последовательности цифр ascii в фактических двоичные целые числа).

Все, что сказано, вероятно, вы, вероятно, можете использовать раздел синтаксического анализа инструмента, поскольку парсеры больше работают над абстрактными токенами, которые их кормят лексером. После создания грамматики на символическом уровне вам нужно будет переделать лексер, чтобы создать маркеры проблем из двоичного потока для подачи на парсер.

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

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

Но рассмотрим случай дизассемблера. Это простой лексер, который может поднять на высоком уровне разные типы инструкций (например, те операнды, которые не имеют аргументов, те, которые принимают один байт в качестве аргумента или слово), и подают его в парсер затем можно использовать для преобразования инструкций в их мнемонику и операнды в обычном синтаксисе ассемблера, а также обрабатывать ссылки на метки и т.д.

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

Addenda:

Если у вас достаточно информации для преобразования двоичного потока в текст для подачи на движок, то у вас есть достаточно информации, а не для создания текста, вы могли бы создать фактические токены, которые синтаксический анализатор хотел бы видеть из lexer.

Тем не менее, что вы можете сделать, это взять текстовый формат, использовать его в качестве основы для вашего инструмента синтаксического анализа и грамматики, а также создать для вас инструменты lexer и parser, а затем, вручную, вы можете протестировать свои анализатора и его обработки с использованием "текстовых тестов".

Но когда вы переходите к чтению двоичного кода, вместо того, чтобы создавать текст, чтобы его можно было лексировать и анализировать, просто создайте маркеры, которые создаст лексер (они должны быть простыми объектами), и непосредственно накачайте парсер. Это сэкономит вам шаг lex и сохранит вам некоторое время обработки.