对于已经以拆分格式给出的大量输入数据,解析器并行化似乎很容易。大量的单个数据库条目,或者易于通过快速的预处理步骤进行拆分,例如解析大文本中句子的语法结构。
似乎很难进行并行解析,这已经需要付出很多努力才能在给定输入中定位子结构。通用编程语言代码看起来像一个很好的例子。在Haskell之类的使用布局/缩进来分隔各个定义的语言中,找到新定义的开始后,您可能可以检查每行的前导空格数,跳过所有行,直到找到另一个定义并传递每个定义跳过块到另一个线程进行完全解析。
对于使用平衡括号定义范围的C,JavaScript等语言,进行预处理的工作量会更高。您需要遍历整个输入,从而计算大括号,注意字符串文字中的文本,等等。对于XML之类的语言而言,情况更糟,您还需要在开始/结束标签中跟踪标签名称。
我发现a parallel version of the CYK parsing algortihm似乎适用于所有与上下文无关的语法。但是我很好奇还有什么其他通用概念/算法可以使解析器并行化,包括上述大括号计数这样的事情,它们仅适用于有限的一组语言。这个问题不关乎具体的实现,而是有关实现的思想。
答案 0 :(得分:4)
我认为您会发现McKeeman于1982年在Parallel LR Parsing上发表的论文非常有趣,因为它似乎很实用并且适用于广泛的语法。
基本方案是标准LR解析。聪明的是,(大概长的)输入被分为大约N个相等大小的块(对于N个处理器),并且每个块都被分别解析。因为块的起点可能(必须!)在某些生产的中间,所以与经典的LR解析器不同,McKeemans的单个解析器从所有可能的左上下文(要求增强LR状态机)开始确定哪个LR。项目适用于块。 (在单个解析器确定什么状态真正适用之前,不应该花费太多的令牌,因此这并不是很低效)。然后将所有解析器的结果缝合在一起。
他有点回避在令牌中间划分输入的问题。 (您可以想象一个任意大的字符串文字,其中包含看起来像代码的文本,以欺骗解析器从中间开始)。似乎发生的情况是解析器遇到错误并放弃了解析;左侧的解析器占用了空闲时间。可以想象,分块器会使用一些聪明的东西来避免这种情况。
他去演示一个真正的解析器,在其中可以获得加速。
确实聪明。