LR(1)解析器状态大小仍然是个问题?

时间:2014-06-11 23:54:14

标签: parsing compiler-construction grammar lalr lr

历史上,LALR(1)解析器优于LR(1)解析器,因为LR(1)解析器生成的大量状态需要资源要求。很难相信这仍然是当今计算环境中的一个问题。这仍然是这种情况,还是现在使用规范的LR解析器构建的现代编译器,因为LALR语法是LR语法的适当子集?

2 个答案:

答案 0 :(得分:4)

LR(1)解析器的主要问题是表大小,表大小会以某种方式受到伤害。

如果你有一个LR(1)解析器有10,000,000个状态(并非所有那些不常见),例如50个非终结符和50个终端(并非所有不合理),你将拥有一个包含10亿个条目的表。如果每个条目甚至使用一个字节,那么现在只需要1GB的空间来保存表。那个空间要么在应用程序二进制文件中,在这种情况下你现在有一个1GB的可执行文件,或者它是动态生成的,在这种情况下你现在需要1GB的RAM加上填充它的时间。这些都不是很有吸引力。

如果你有那种记忆,你绝对可以使用LR(1)解析器,但这不是一个好主意。首先,应用程序二进制文件的大小将是巨大的。这将使分发应用程序变得困难。其次,将表加载到内存中的行为需要将大约1GB的数据从磁盘传输到RAM中,这将非常慢。还存在分析进出分析表的问题。如果操作系统不能很好地驱逐页面,那么最终可能会出现颠簸,降低性能的可能性。

虽然您可以将解析器放在服务器上,但这通常不会立即完成,并且需要通过网络完成所有编译。

还有一个问题是它是否值得。解析器的资源成本大幅增加需要通过解析质量的一些比例优势来证明。在实践中,LALR解析器适用于许多语法。对于那些不起作用的人来说,像IELR或GLR这样的新解析算法对于LR(1)来说是一个更好的选择,因为它们提供相同的解析能力(或者在GLR的情况下更多),并且空间显着减少。因此,您最好使用这些算法。

总而言之,是的,你今天可以使用LR(1),但是它会因为资源效率低而使用另一种解析算法会更好。

希望这有帮助!

答案 1 :(得分:2)

最小LR(1)解析器解决了这个问题。 Pager博士是第一个在1977年写一篇关于如何做到这一点的论文。最小的LR(1)解析器具有规范LR(1)解析器的所有功能,识别LR(1)语法定义的相同语言。但是,最小的LR(1)解析器具有几乎与LALR(1)解析器表一样小的解析器表。

所需的技巧是在构建规范LR(1)状态机时合并兼容状态。这很复杂,前瞻设置计算与LALR(1)一样复杂。但最终的结果是beautitul。

顺便说一句,LRSTAR Parser Generator创建了最小的LR(1)和最小的LR(k)解析器,非常强大。