408 字
2 分钟
编译原理: 自底向上的LR分析

本文更新于2024-05-28 20:23:46

1. LR(0)LR(0)分析#

1.1 可归前缀和活前缀#

定义1.1.11.1.1 如果文法GG拓广文法GG'正规推导SαAωRαβωS' \mathop{\Rightarrow}\limits^* \alpha A\omega \mathop{\Rightarrow}\limits_R \alpha \beta \omega,且若γ\gamma是串αβ\alpha \beta的一个前缀,则γ\gamma是文法GG'GG的一个活前缀γ\gamma规范句型αβω\alpha \beta \omega的前缀,但是它不会超过αβω\alpha \beta \omega句柄的右端。

如果γ=αβ\gamma = \alpha\betaγ\gamma是文法GG的一个可归前缀

TIP

LR(0)LR(0)分析方法实际上就是在不断列出αβ\alpha \beta的前缀,一旦出现αβ\alpha\beta也就是出现了可归前缀,就立刻使用AβA\to \beta归约句柄。

1.2 求解活前缀与可归前缀#

如果GG是一个上下文无关文法,GG'是其拓广文法,对每一个非终结符AA,定义LC(A)LC(A)运算。

LC(A)={αSαAω,AVN,ωVT}LC(A) = \{\alpha|S'\mathop{\Rightarrow}\limits^*\alpha A\omega, A\in V_N,\omega \in V_T^*\}
TIP

LC(A)LC(A)运算的结果是所有包含有AA的正规句型中AA左边的符号串。

通过LC(A)LC(A)就能找出所有不包含句柄的活前缀。

定理1.1.11.1.1 若有产生式BαAωB \to \alpha A \omega,则LC(A)LC(B)×{α}LC(A) \supseteq LC(B) \times \{\alpha\}

通过该定理,依次列方程LC(A)LC(A):

LC(S)={ε}LC(S)=\begin{align} LC(S') = \{\varepsilon\} \\ LC(S) = \cdots \end{align}

LC(A)LC(A)只求出了非终结符AA在未被替换时左部可能产生的串,还未能形成句柄。定义产生式AβA \to \betaLR(0)CONTEXT(Aβ)LR(0)CONTEXT(A\to\beta)运算:

LR(0)CONTEXT(Aβ)=LC(A)×{β}LR(0)CONTEXT(A\to \beta) = LC(A) \times \{\beta\}

得到的串就都是可归前缀

以每一个产生式AβA\to \betaLR(0)CONTEXT(Aβ)LR(0)CONTEXT(A\to \beta)构造一个NFANFA,终态为可归前缀。接着从开始状态XX连空弧向每一个NFANFA,得到一个大NFANFA,该NFANFA

编译原理: 自底向上的LR分析
http://blog.fragments.work/posts/principleofcompiling/ch5/
作者
Lixin WANG
发布于
2024-05-28
许可协议
CC BY-NC-SA 4.0