2009-10-08 3 views
1

Je travaille sur un protocole réseau de base en Python, qui devrait pouvoir transférer à la fois des chaînes ASCII (lire: terminé par EOL) et des données binaires. Pour que ce dernier soit possible, j'ai choisi de créer la grammaire telle qu'elle contienne le nombre d'octets à venir qui vont être binaires.SimpleParse grammaire non-déterministe jusqu'à l'exécution

Pour SimpleParse, la grammaire ressemblerait à ceci [1] jusqu'à présent:

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, '}' 

Le problème est que je ne sais pas comment instruisent SimpleParse que les éléments suivants va être un mandrin de données binaires de SIZE_INTEGER octets à l'exécution.

La cause en est la définition du terminal BINARY_VALUE qui répond à mes besoins actuels, donc il ne peut pas être changé.

Merci

Modifier

Je suppose que la solution serait dit à arrêter quand il correspond à la binary_attribute de production et de me laisser alimenter le nœud AST manuellement (via socket.recv()), mais comment faire cela?

Edit 2

base64 codage ou similaire ne constitue pas une option.

[1] Je have't testé, donc je ne sais pas si cela fonctionne dans la pratique, il est seulement pour vous faire une idée

+0

juste pour mieux comprendre, quel genre de générateur d'analyseur utilisez-vous? (si seulement). Je ne connais pas grand-chose à propos de python mais avez-vous regardé tordu, je suppose que vous pouvez implémenter un nouveau protocole dans le framework/library – LB40

+0

Regardez * "Class" de Parsers Generated * à http://simpleparse.sourceforge.net/ Twisté semble intéressant, mais trop à part entière (et lourd) pour mes besoins. Peut-être que je l'utiliserai pour un autre projet. – Flavius

+0

ASCII est un sous-ensemble de binaire, donc la première question est de savoir pourquoi vous devez séparer les deux en premier lieu? –

Répondre

1

Si vous voulez que votre application soit portable et fiable, je vous suggère de ne transmettre que des caractères ASCII standard sur le fil.

Différentes architectures d'ordinateur ont différentes représentations binaires, différentes tailles de mots, différents jeux de caractères. Il y a trois approches pour traiter cela.

Tout d'abord, vous pouvez ignorer les problèmes et espérer que vous n'aurez plus qu'à implémenter le protocole sur une seule paltform. Deux, vous pouvez aller tout informatique et de venir avec un "formulaire cardinal" pour chaque type de données possible dans un CORBA.

Vous pouvez être pratique et utiliser la magie de "sprintf" et "scanf" pour traduire vos données vers et à partir de caractères ASCII simples lors de l'envoi de données sur le réseau.

Je suggère également que votre protocole inclut une longueur de message au début ou près du début du message. Le bogue le plus commun dans les protocoles faits maison est que le partenaire de réception attend plus de données que ce qui a été envoyé et attend ensuite pour toujours des données qui n'ont jamais été envoyées.

4

Si la grammaire est aussi simple que celui que vous avez cité, puis peut-être utiliser un générateur d'analyseur est trop? Vous pourriez trouver que rouler votre propre analyseur récursif à la main est plus simple et plus rapide.

0

Je vous recommande fortement d'utiliser la bibliothèque construct pour analyser les données binaires. Il supporte aussi le texte (ASCII), donc quand il détecte du texte, vous pouvez le passer à votre analyseur basé sur SimpleParse, mais les données binaires seront analysées avec construct. C'est très pratique et puissant.

Questions connexes