parsing - 使用 FParsec 进行分块解析

标签 parsing f# fparsec

是否可以像从套接字一样将输入以块的形式提交给 FParsec 解析器?如果没有,是否可以检索输入流的当前结果和未解析部分,以便我可以完成此操作?我正在尝试运行来自 SocketAsyncEventArgs 的输入块无需缓冲整个消息。

更新

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

终极问题:

  • 我可以在我的 Stream 下使用循环缓冲区吗?传递给 CharStream ?
  • 在这种情况下,我不需要担心手动控制分块吗?
  • 最佳答案

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

    但是请注意,CharStream将以固定(但可配置)大小的块消耗输入流,即它将调用 Read System.IO.Stream的方法尽可能频繁地填充一个完整的块。因此,如果您解析输入的速度比检索新输入的速度快,CharStream即使已经有一些未解析的输入,也可能会阻塞,因为还没有足够的输入来填充一个完整的块。

    更新

    终极问题的答案:42。

  • 您如何实现 Stream从中构建 CharStream完全取决于你。您记得的排除并行访问的限制仅适用于 CharStream类,这不是线程安全的。
  • 实现 Stream作为循环缓冲区可能会restrict the maximum distance over which you can backtrack.
  • CharStream的块大小当 Stream 出现时,您可以回溯多远影响不支持求。
  • 异步解析输入的最简单方法是在异步任务中(即在后台线程上)进行解析。在任务中,您可以简单地同步读取套接字,或者,如果您不信任操作系统的缓冲,您可以使用像 BlockingStream 这样的流类。在您在下面的第二条评论中链接的文章中进行了描述。
  • 如果输入可以很容易地分成独立的块(例如,用于基于行的文本格式的行),那么自己将其分块然后逐块解析输入块可能更有效。
  • 关于parsing - 使用 FParsec 进行分块解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8891019/

    相关文章:

    Java - Decimal Format.parse 以返回具有指定小数位数的 double 值

    php - MySQL 表和 JSON 解析。是否有外键?

    ios - 核心数据插入和保存缓慢

    f# - SqlProvider 递归组合查询

    f# - FParsec 在很多方面都失败了

    parsing - FParsec - 解析器序列

    c++ - 在 C++ 中快速解析制表符分隔的字符串和整数

    .net - 像 Java 在 F# 中的静态导入一样吗?

    scala - 是否可以使用延续使foldRight尾递归?

    f# - FParsec 的缩进、表达式、语句和 StackOverflowException - 错误