Существуют ли какие-либо известные библиотеки комбинаторов синтаксических анализаторов в F #, которые могут анализировать двоичные (не текстовые) файлы?

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

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


person 7sharp9    schedule 17.10.2011    source источник
comment
Я думаю, что упомяну об этом 2 года спустя, но я работаю над проектом, который делает именно это. У меня есть образец двоичного анализатора контейнера mp4, написанный с использованием комбинаторов стиля fparsec. github.com/devshorts/ParsecClone   -  person devshorts    schedule 16.08.2013


Ответы (2)


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

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

person Tomas Petricek    schedule 17.10.2011
comment
Мне кажется, я помню термин "пиклёр" из книги Expert F#... Спасибо, Томас, я тоже их проверю. Это напоминает мне, что я собирался проверить возобновления, которые вы упомянули в компиляторе F #, не так ли. - person 7sharp9; 18.10.2011
comment
@Tomas Просматривая документ по ссылке, которую вы отправили, вы ответили на вопрос, который вы задали мне об полезности преобразования worker/wrapper. См. обсуждение реализации сборщиков в ML в конце вашей ссылки. - person ; 18.10.2011
comment
Я иду за монадическими маринадами :-) - person 7sharp9; 19.10.2011
comment
@Ryan Хм, это звучит довольно интересно, похоже, преобразования worker/wrapper действительно могут быть весьма полезными. Хотел бы я иметь больше времени, чтобы поиграть с этим :-). - person Tomas Petricek; 19.10.2011
comment
ссылка на pdf не работает. Это это то, что это должно указывать на? - person Julian; 06.10.2018
comment
@ Джулиан Да! Спасибо - исправил ссылку в ответе. - person Tomas Petricek; 07.10.2018

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

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

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

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

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

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

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

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

Дополнения:

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

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

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

person Will Hartung    schedule 17.10.2011
comment
Прежде всего спасибо за подробный ответ. Я собирался работать с предпосылкой, что буду работать с подмножеством грамматики низкого уровня и компоновать его вверх в блоки, которые можно будет обработать чем-то вроде fparsec. т. е. (pbyte 0x45) ››= fun x -> (pbyte 0x78) и т. д. Затем используйте эти блоки для создания, возможно, текста, который затем может быть обработан fparsec. - person 7sharp9; 18.10.2011