并行化解析器存在哪些概念或算法?



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

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

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

情况更糟。我发现了 CYK 解析算法的并行版本,它似乎适用于所有上下文无关的语法。但我很好奇还有哪些其他通用概念/算法可以并行化解析器,包括上面描述的大括号计数,它仅适用于有限的语言集。这个问题不是关于具体的实现,而是关于这些实现所基于的思想。

我想你会发现McKeeman在1982年关于并行LR解析的论文非常有趣,因为它看起来很实用,适用于广泛的语法类。

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

他有点回避了在令牌中间对输入进行分区的问题。(你可以想象一个任意大的字符串文字,其中包含看起来像代码的文本,以欺骗解析器中间的开头(。 似乎发生的事情是解析器遇到错误,并放弃其解析;其左侧的解析器占用了松弛。 可以想象块拆分器使用一点点智能来避免这种情况。

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

确实很聪明。

最新更新