2009-10-08 2 views
1

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

Для 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, которое удовлетворяет мои потребности, как и сейчас, поэтому его нельзя изменить.

Благодаря

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

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

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

Base64-кодирование или подобное не вариант.

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

+0

только для того, чтобы лучше понять, какой генератор парсера вы используете? (если есть). Я не знаю много о python, но вы посмотрели на скручен, я предполагаю, что вы можете реализовать любой новый протокол в фреймворке/библиотеке. – LB40

+0

Посмотрите на * «Класс» генерируемых парсеров * по адресу http://simpleparse.sourceforge.net/ Скрученный выглядит интересным, но слишком полноценным (и тяжелым) для моих нужд. Возможно, я буду использовать его для другого проекта. – Flavius

+0

ASCII - это подмножество двоичных файлов, поэтому первый вопрос заключается в том, почему вам нужно разделить их в первую очередь? –

ответ

1

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

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

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

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

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

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

4

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

0

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