Есть ли в F # известные библиотеки комбинаторов синтаксического анализатора, которые могут анализировать двоичные (не текстовые) файлы? - PullRequest
13 голосов
/ 18 октября 2011

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

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

Ответы [ 2 ]

12 голосов
/ 18 октября 2011

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

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

6 голосов
/ 18 октября 2011

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

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

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

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

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

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

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

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

Дополнения:

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

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

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

...