【问题标题】:Incremental Stream Parsing in C++C++ 中的增量流解析
【发布时间】:2011-03-15 13:31:50
【问题描述】:

我正在使用非阻塞 read() 函数(在 C/C++ 中)从(串行)端口读取数据。 这意味着每次我“轮询”端口时,数据都会以未确定(但已报告)大小(包括 0)的块进入。然后我需要为某些模式(不是 XML)解析这个“流”。

每次 read() 返回非零缓冲区时,我的幼稚实现将新字符串连接到前一个流字符串,并重新解析整个字符串。 当模式匹配时,相关部分被丢弃,只留下字符串的尾部。

显然有更有效的方法可以做到这一点,例如,增量解析 a-la SAX、类似双端队列的缓冲区或类似的字符串切片等。 另外,很明显,我不是第一个必须进行这种类型的流解析的人。

有没有人知道任何图书馆已经在做这种事情? 在缺少模式匹配的情况下防止内存溢出也是一大优势。

谢谢, 阿迪

【问题讨论】:

  • 你需要做什么样的模式匹配?
  • 我必须支持几种不同的设备,所以我想要一个更通用的解析器。目前,我查找页眉字符串和页脚字符串并返回此“句子”以供以后进行额外解析。实际上,我希望有一个更通用的解析器,例如正则表达式。

标签: c++ parsing stream nonblocking


【解决方案1】:

您可以根据自己的模式做一些技巧。

  • 寻找一个像换行符这样的字符,您只需要扫描字符串的新部分。
  • 如果您正在寻找\r\n,那么您只需扫描从前一部分的最后一个字符开始的新部分。
  • 如果您有一个带有已知结尾部分的模式,那么您只需扫描该结尾即可知道是否需要扫描整个缓冲区。
  • 如果您有某种同步字符,例如 C/C++ 中的分号,那么您可以在找到时解析或声明解析错误。

【讨论】:

  • 如果模式是正则表达式怎么办?在没有更多信息的情况下回答还为时过早,IMO。
  • @Moron:您仍然可以将这些技巧与正则表达式一起使用。如果您的正则表达式具有静态结束模式,您可以在运行整个正则表达式之前在新的缓冲区数据中查找它。
  • @Zan:假设正则表达式是 ^someregex$。然后我们可以通过构造一个 DFA 并通过它运行流来在恒定空间中解决这个问题。
  • 我必须支持几种不同的设备,所以我想要一个更通用的解析器。目前,我查找页眉字符串和页脚字符串并返回此“句子”以供以后进行额外解析。实际上,我希望有一个更通用的解析器,例如正则表达式。另外,我正在寻找一些东西,它还可以将流从通过流接收的数据块中组合在一起。我现在正在查看 Boost.Asio,看看它是否适合这个。
  • @Moron:如果您可以访问 DFA 实施的核心,那么您可以将数据以读取缓冲区大小的块的形式输入 DFA。在这种情况下,您永远不会从头开始重新解析缓冲区。
猜你喜欢
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-07
  • 1970-01-01
相关资源
最近更新 更多