SimpleParse недетерминированная грамматика до времени выполнения - PullRequest
1 голос
/ 08 октября 2009

Я работаю над базовым сетевым протоколом в Python, который должен иметь возможность передавать как строки ASCII (читай: завершенные EOL), так и двоичные данные. Чтобы последний был возможен, я решил создать грамматику так, чтобы она содержала количество байтов, которые будут двоичными.

Для SimpleParse грамматика будет выглядеть так [1]:

EOL := [\n]
IDENTIFIER := [a-zA-Z0-9_-]+
SIZE_INTEGER := [1-9]*[0-9]+
ASCII_VALUE := [^\n\0]+, EOL
BINARY_VALUE := .*+
value := (ASCII_VALUE/BINARY_VALUE)

eol_attribute := IDENTIFIER, ':', value
binary_attribute := IDENTIFIER, [\t], SIZE_INTEGER, ':', value
attributes := (eol_attribute/binary_attribute)+ 

command := IDENTIFIER, EOL
command := IDENTIFIER, '{', attributes, '}'

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

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

Спасибо

Редактировать

Я полагаю, что решение заставит его остановиться, когда он совпадет с производственным двоичным_атрибутом, и позволит мне заполнить узел AST вручную (через socket.recv ()), но как это сделать?

Редактировать 2

Base64-кодирование или аналогичное не вариант.

[1] Я не проверял это, поэтому я не знаю, работает ли он практически, это только для вас, чтобы получить представление

Ответы [ 3 ]

4 голосов
/ 21 октября 2009

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

1 голос
/ 27 октября 2009

Если вы хотите, чтобы ваше приложение было переносимым и надежным, я бы посоветовал вам передавать только стандартные символы ASCII по проводам.

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

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

Два, вы можете пойти на все компьютерные курсы и придумать «кардинальную форму» для каждого возможного типа данных ala CORBA.

Вы можете быть практичным и использовать магию «sprintf» и «scanf» для перевода ваших данных в простые символы ASCII и из них при отправке данных по сети.

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

0 голосов
/ 24 октября 2009

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

...