使用FParsec进行分块解析

时间:2012-01-17 07:27:12

标签: parsing f# fparsec

是否可以以块的形式向FParsec解析器提交输入?如果没有,是否可以检索输入流的当前结果和未解析部分,以便我可以完成此操作?我正在尝试运行来自SocketAsyncEventArgs的大量输入而不缓冲整个消息。

更新

注意使用SocketAsyncEventArgs的原因是表示将数据发送到CharStream可能会导致对基础Stream的异步访问。具体来说,我正在寻找使用循环缓冲区来推送来自套接字的数据。我记得FParsec文档指出不应该异步访问底层Stream,所以我计划手动控制分块解析。

终极问题:

  1. 我可以使用传递给Stream的<{1}}下的循环缓冲区吗?
  2. 在这种情况下,我不需要担心手动控制分块吗?

1 个答案:

答案 0 :(得分:8)

正常版本的FParsec(虽然不是Low-Trust version)读取输入块,或“块状”,正如我在CharStream documentation中所说的那样。因此,如果从CharStream构造System.IO.Stream并且内容足够大以跨越多个CharStream块,则可以在完全检索输入之前开始解析。

但请注意,CharStream将使用固定(但可配置)大小的块中的输入流,即它会像Read那样经常调用System.IO.Stream方法。有必要填补一个完整的块。因此,如果您以比检索新输入更快的速度解析输入,CharStream可能会阻止,即使已经有一些未解析的输入,因为还没有足够的输入来填充整个块。

<强>更新

你最终问题的答案: 42。

  • 如何实施构建Stream的{​​{1}}完全取决于您。您记住的排除并行访问的限制仅适用于CharStream类,这不是线程安全的。

  • CharStream实现为循环缓冲区可能会restrict the maximum distance over which you can backtrack.

  • Stream的块大小会影响CharStream不支持搜索时可以回溯的距离。

  • 异步解析输入的最简单方法是在异步任务中(即在后台线程上)进行解析。在任务中,您可以简单地同步读取套接字,或者,如果您不信任操作系统的缓冲,则可以使用流式类,如下面第二条评论中链接的文章中描述的Stream

  • 如果输入可以很容易地分成独立的块(例如,基于行的文本格式的行),那么自己将其分块然后按块解析输入块可能更有效。