typora-copy-images-to: assets/${filename}

3.6.2 Reducing the size of LR(1) tables

不幸的是,LR(1) table 即使是很少的语法也会很大。所以存在很多技术来降低 LR(1) 的表大小。本节描述这些方法

Shrinking the grammar

编译器开发可以重新编码 grammar 来减少 productions.

Using other construction algorithms

构造 LR 类型的 parser 存在几种其他算法。包括 SLR(1) , LALR(1)。都可以产出比 canonical LR(1) 算法更小的 table

SLR(1) [simple LR(1)] 算法接受比 canonical LR(1) 算法更少的 grammars。受限可以使得 table-filling 算法在 shift entries 和 reduce entries 使用 FOLLOW sets 区分出来,消除了 lookahead symbols 的需要。所以只需要更少的状态,table 就更小。这种技术实际应用在很多实际应用。

LALR(1) [lookahead LR(1)] 算法基于这样一种观察,表示状态的核心项很关键,而其他项只是用来计算 closure。LALR(1) table 结构使用核心项计算 canonical 集合,在到达固定位置计算其 closure。产生的权威集合类似于 SLR 的大小,不同的细节在于,表更小。

本章开始介绍的 canonical LR(1) 算法是最通用的表生成算法。产生最大的表,同时可以接受最多的 grammars。使用合适的表缩小技术,LR(1) 的表可以通过更多的限制来缩小。

可以接受的语法排序位 LR(1) > LALR(1) > SLR(1)。但是违反直觉的是,任何有 LR(1) grammar 的语言也同时有 SLR(1) 和 LALR(1) 。这些更具限制的构造算法必须在 shift actions 和 reduce actions 区分。