如何在 nom 中创建流解析器?

w.b*_*ian 5 rust nom

我已经在 nom 中创建了一些重要的解析器,所以我现在对它非常熟悉。到目前为止,我创建的所有解析器总是向解析器提供整个输入切片。

我想创建一个流解析器,我认为这意味着我可以继续将字节输入解析器,直到它完成。我很难找到任何说明这一点的文档或示例,而且我也质疑我对“流式解析器”是什么的假设。

我的问题是:

  • 我对流式解析器的理解是否正确?
  • 如果是这样,是否有使用这种技术的解析器的好例子?

Ste*_*fan 4

nom解析器既不维护缓冲区来输入更多数据,也不维护以前需要更多字节的“状态”。

但是,如果您查看结构,IResult您会发现您可以返回部分结果或表明您需要更多数据。

似乎提供了一些结构来处理流:我认为您应该Consumer使用宏从解析器创建 a consumer_from_parser!Producer为您的数据源实现 a ,然后调用run直到它返回None(当您有更多数据时再次开始)。到目前为止,示例和文档似乎大多缺失 - 请参阅https://github.com/Geal/nom的底部:)

此外,看起来大多数函数和宏在nom到达输入末尾时的行为都没有得到很好的记录(或根本没有记录)。例如,如果输入的长度不足以包含要查找的 ,则take_until!返回,但如果输入足够长但不包含 ,则返回错误。Incompletesubstrsubstr

nom大多使用&[u8]or&str作为输入;您无法通过这些类型发出实际的“流结束”信号。您可以实现自己的输入类型(相关特征:)nom::{AsBytes,Compare,FindSubstring,FindToken,InputIter,InputLength,InputTake,Offset,ParseTo,Slice}来添加“已到达流末尾”标志,但nom提供的宏和函数将无法解释它。

总而言之,我建议通过其他方式将流式输入拆分为可以使用简单的非流式解析器处理的块(甚至可以使用synom而不是nom)。