历史上,由于LR(1)分析器生成大量状态所需的资源要求,LALR(1)分析器比LR(1)分析器更受欢迎。很难相信这在今天的计算环境中仍然存在问题。现代编译器是否使用规范LR分析器构建,因为LALR语法是LR语法的一个子集?
LR(1)解析器的主要问题是表格大小,而且表格大小会以某种方式对其造成伤害。假设您拥有一个具有1000万个状态(并不罕见)的LR(1)解析器,在其中有50个非终端符和50个终端符(也不算不合理),那么您将拥有一个包含10亿个条目的表格。如果每个条目使用了一个字节,现在你需要1GB的空间来保存这个表格。这个空间或者在应用程序二进制文件中,这样你就有了一个1GB的可执行文件,或者是动态生成的,这样你现在需要1GB的RAM加上填充时间。这两种情况都不是很吸引人。当然,如果你有那么多的内存,你绝对可以使用LR(1)解析器,但这不是一个好主意。首先,应用程序二进制文件的大小将是巨大的。这将使分发应用程序变得困难。其次,将表格加载到内存中的行为将需要将大约1GB的数据从磁盘转移到RAM中,这将是极其缓慢的。还存在分页解析表格的问题。如果操作系统不能很好地逐出页面,你可能会遇到交换现象,导致性能不可接受的下降。虽然您可以将解析器放在服务器上,但目前通常不这样做,并且需要在网络上完成所有编译。还有一个问题是是否值得。解析器所需的资源成本的急剧增加必须通过某种比例上的解析质量获得证明。实际上,LALR解析器可以适用于许多语法。对于它无法处理的语法,像IELR或GLR这样的新解析算法将是LR(1)的优良选择,因为它们提供相同的解析能力(在GLR的情况下更多)并显著减少了空间占用。因此,你最好使用那些算法。总之,是的,您今天可以使用LR(1),但它的资源效率如此低下,以至于您最好使用另一种解析算法。希望这可以帮助到您!
最小LR(1)解析器可以解决这个问题。1977年,Pager博士是第一个撰写有关如何做到这一点的论文的人。最小LR(1)解析器具有规范LR(1)解析器的所有功能,可以识别由LR(1)语法定义的相同语言。然而,最小LR(1)解析器的解析表几乎与LALR(1)解析表一样小。所需技巧是在构建规范LR(1)状态机时合并兼容状态。这很复杂,向前看集合计算与LALR(1)一样复杂。但最终结果是美丽的。顺便说一下,LRSTAR Parser Generator创建最小LR(1)和最小LR(k)解析器,非常强大。