SimpleParse非确定性语法,直到运行时

时间:2009-10-08 13:11:07

标签: python parsing text-parsing

我正在使用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()),但是怎么做? < / p>

修改2

Base64编码或类似功能不是一种选择。

[1]我没有测试过,所以我不知道它是否真的有用,只是为了让你有所了解

3 个答案:

答案 0 :(得分:4)

如果语法和你引用的语法一样简单,那么使用解析器生成器可能有点过分了吗?您可能会发现手动滚动自己的递归解析器更简单,更快捷。

答案 1 :(得分:1)

如果您希望您的应用程序具有可移植性和可靠性,我建议您只通过线路传递标准ASCII字符。

不同的计算机体系结构具有不同的二进制表示,不同的字大小,不同的字符集。有三种方法可以解决这个问题。

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

两个你可以使用所有计算机技术,并为每种可能的数据类型ala CORBA提供“基数形式”。

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

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

答案 2 :(得分:0)

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