如何使用YACC解析器同时解析输入文本文件?

时间:2015-02-13 03:22:18

标签: parsing yacc

我也希望将并发解析的结果与串行解析进行比较。 这该怎么做?哪一个是最简单的方法?

2 个答案:

答案 0 :(得分:2)

正如其他人所说,YACC(基于LR解析)本身并不是“并发”。 (据我所知,YACC甚至不能重入,无论你做什么,都会很难在多线程环境中使用它。非重入可能只能用汗水来克服,所以这是一个烦恼,而不是表演限制。)

一个想法是构造一个管道,允许词法分析器尽可能快地将词汇生成到蒸汽中,并让实际的解析器从流中读取。这可以使你充其量只能为2.你可以用YACC相对容易地做到这一点,模数设置通信线程。

McKeeman等人已经实施parallel LR parsing by dividing the file into N chunks for N threads并声称取得了良好的效果。这种方法并不简单,因为将单个文件解析为大小相同的并行块​​并将这些块拼接在一起并不容易。我怀疑是否可以轻易地攻击YACC来做到这一点。

一个棘手的想法是从两个的文件解析到中间。 它很容易从“自然”前向语义定义后向解析器语法:只需反转所有语法规则内容。没有比这更容易的了;这可能会引入前向解析器中不存在的歧义。这个paper combines McKeeman's idea of breaking the file into chunks with bidirectional parsing of each chunk,可以在大文件上找到很多并行性。

更容易做到的是使用您拥有的任何解析技术来并行化单个文件的解析。虽然单个文件的解析时间可能不均匀,但这确实可以很好地并行化,因此最好使用某种工作列表和团队解析器线程来完成此工作列表的工作。您可以组织使用YACC进行此操作。

我们的DMS软件重组工具包(DMS)在阅读大型Java源代码和类时使用了这一概括。解析本身并不是很有用;你几乎总是需要构建符号表。 DMS读取Java因此并行化解析,AST构建和符号表构造。从一组基本文件名开始,它以并行 grain 启动解析(在OS线程之上由DMS复用);当解析器完成时,解析后的树将被传递给名称解析器,该解析器会遇到每个并行范围的并行粒度。嵌套范围会导致生成谷物树。通过将范围的解决方案视为未来(事件)来进一步开展工作;在解析范围时,可以启动更多Java文件解析/名称解析活动;当一个范围被解决时,一个事件被发出信号,然后等待范围完成的谷物可以检查范围内容以解析他们自己的名字。在这个中间的(潜在)并行性的混乱几乎是可怕的: - 但是由DMS的底层并行编程语言PARLANSE管理,它使用工作窃取来平衡线程之间的负载。

经验表明,使用8个内核在生产环境中执行此操作可以使数千个(典型的/ Java意味着很小的)源文件的连续速度提高5倍。我们认为我们知道瓶颈在哪里;就属性语法中的过度同步而言,名称解析器的某些部分比它应该更昂贵。我怀疑我们可以接近8.因此,并行解析和名称解析可能非常有效。

我们对C ++ 14的表现不尽相同,因为它所读取的#includes上的各个文件的所有依赖关系,通常在不同的预处理器配置中。

答案 1 :(得分:0)

如果输入允许分割成块,例如,日志文件行,可以并行解析,然后您可以使用producer/consumer queue并行解析一定数量的此类块,然后加入解析结果。