1

我正在使用 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 的定义满足了我现在的需求,因此无法更改。

谢谢

编辑

我想解决方案会告诉它在它与生产 binary_attribute 匹配时停止并让我手动填充 AST 节点(通过 socket.recv()),但该怎么做呢?

编辑 2

Base64 编码或类似的不是一个选项。

[1]我没有测试过,所以不知道是否实用,仅供大家参考

4

3 回答 3

4

如果语法像您引用的那样简单,那么使用解析器生成器可能是矫枉过正?您可能会发现手动滚动您自己的递归解析器更简单、更快捷。

于 2009-10-21T09:59:28.587 回答
1

如果您希望您的应用程序可移植且可靠,我建议您仅通过网络传递标准 ASCII 字符。

不同的计算机体系结构具有不同的二进制表示、不同的字长、不同的字符集。有三种方法来处理这个问题。

首先,您可以忽略这些问题,并希望您只需要在单个平台上实现该协议。

两个你可以学习所有计算机科学并为每种可能的数据类型ala CORBA提出一个“基本形式”。

通过网络发送数据时,您可以实用并使用“sprintf”和“scanf”的魔力将数据转换为纯 ASCII 字符或从纯 ASCII 字符转换。

我还建议您的协议在消息开头或附近包含消息长度。自制协议中最常见的错误是接收伙伴期望的数据多于发送的数据,然后永远等待从未发送的数据。

于 2009-10-27T01:55:42.580 回答
0

我强烈建议您考虑使用构造库来解析二进制数据。它还支持文本 (ASCII),因此当它检测到文本时,您可以将其传递给基于 SimpleParse 的解析器,但二进制数据将使用构造进行解析。它非常方便且功能强大。

于 2009-10-24T06:11:01.933 回答