【问题标题】:What concepts or algorithms exist for parallelizing parsers?并行化解析器有哪些概念或算法?
【发布时间】:2019-01-29 16:10:33
【问题描述】:

对于已经以拆分格式给出的大量输入数据,并行化解析器似乎很容易,例如单个数据库条目的大列表,或者很容易通过快速预处理步骤进行拆分,例如解析大文本中句子的语法结构。

似乎更难的是并行解析,它已经需要相当多的努力来定位给定输入中的子结构。通用编程语言代码看起来是一个很好的例子。在像 Haskell 这样使用布局/缩进分隔各个定义的语言中,您可能会在找到新定义的开头后检查每行的前导空格数,跳过所有行直到找到另一个定义并传递每个将块跳过到另一个线程进行完整解析。

当涉及到像 C、JavaScript 等使用平衡大括号来定义范围的语言时,进行预处理的工作量会高得多。您需要遍历整个输入,从而计算大括号,处理字符串文字中的文本等等。更糟糕的是,像 XML 这样的语言,您还需要跟踪开始/结束标签中的标签名称。

我发现a parallel version of the CYK parsing algortihm 似乎适用于所有上下文无关语法。但我很好奇确实存在哪些其他通用概念/算法可以并行化解析器,包括上述仅适用于有限语言集的括号计数之类的东西。这个问题不是关于具体的实现,而是这些实现所基于的想法。

【问题讨论】:

  • 鉴于大多数解析器将大部分时间花在词法分析上,我怀疑在查找子结构需要几乎完整的词法分析时,在实际案例中会看到很大的收获。
  • @Henry:是的,词法分析是你必须优化的东西。 OTOH,如果您的 (C++) 编译器以优化的词法速度读取一百万行文本,您仍然可能希望在多核系统上加速 8-32 倍。是的,您仍然需要进行完整的词法分析,但您仍然可以这样做;阅读我关于 McKeeman 如何处理它的答案。

标签: algorithm parsing parallel-processing


【解决方案1】:

我认为您会发现 McKeeman 1982 年关于 Parallel LR Parsing 的论文非常有趣,因为它看起来很实用并且适用于广泛的语法类别。

基本方案是标准的 LR 解析。聪明的是(可能很长)输入被分成大致 N 个大小相等的块(对于 N 个处理器),并且每个块都被单独解析。因为一个块的起始点可能(必须!)在一些产生式的中间,所以 McKeemans 的单个解析器与经典的 LR 解析器不同,它从所有可能的左上下文开始(需要增加 LR 状态机)来确定哪个 LR项目适用于块。 (在单个解析器确定真正应用哪些状态之前,它不应该占用很多标记,因此这不是非常低效的)。然后将所有解析器的结果拼接在一起。

他有点回避在令牌中间划分输入的问题。 (你可以想象一个任意大的字符串文字,其中包含看起来像代码的文本,以欺骗解析器中间的开头)。似乎发生的是解析器遇到错误并放弃解析;左边的解析器填补了这个漏洞。可以想象分块器使用一点点聪明才智来避免这种情况。

他演示了一个真正的解析器,在该解析器中获得了加速。

确实很聪明。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多