写在编译原理考试前

明天还要考最后一门编译原理,正好有一个周末可以准备。今天看了两遍「龙书」,昨天打了一天的《茶杯头》,这个周末恐怕是和龙过不去了:

Chomsky 文法分类体系

https://en.wikipedia.org/wiki/Chomsky_hierarchy

短语、直接短语和句柄

  • 从抽象语法树的角度来看:

    • 短语(Phrase)是某个子树的叶子节点序列。

    • 直接短语(Simple Phrase)是不包含其它子树的子树的叶子节点序列。

    • 句柄(Handle, i.e. Left-Most Simple Phrase)是最左直接短语。

  • 句柄 直接短语 短语。

FIRST

  • 串首终结符:串首第一个符号,并且是终结符。

  • 给定一个文法符号串 αα串首终结符集 FIRST(α) 被定义为可以从 α 推导出的所有串首终结符构成的集合。如果 αϵ,那么 ϵ 也在 FIRST(α) 中。

    • ϵ 的串首终结符集为空集,即 FIRST(ϵ)={}

    • 如果 ϵFIRST(α),那么 FIRST(αβ)=FIRST(α)

    • 如果 ϵFIRST(α),那么 FIRST(αβ)=FIRST(α)FIRST(β)

FOLLOW

  • 非终结符 A后续符号集 FOLLOW(A):可能在某个句型中紧跟在 A 后边的终结符 a 的集合。如果 A 是某个句型的最右符号,则将结束符「$」添加到 FOLLOW(A) 中。

SELECT

  • 产生式 Aβ可选集是指可以选用该产生式进行推导时对应的输入符号的集合,记为 SELECT(Aβ)

    • 条件 SELECT(Aαβ)={α} 满足。

    • 条件 SELECT(Aϵ)=FOLLOW(A) 满足。

  • LL(1) 文法中,产生式 Aa 的可选集:

    • 如果 ϵFIRST(α),那么 SELECT(Aα)=FIRST(α)

    • 如果 ϵFIRST(α),那么 SELECT(Aα)=(FIRST(α){ϵ})FOLLOW(A)

LL(1) 文法

一个文法 GLL(1) 的,当且仅当 G 的任意两个不同的产生式 Aαβ 满足下面的条件:

  • 如果 αβ 均不能推导出 ϵ,则 FIRST(α)FIRST(β)=ϕ,这样可以保证 SELECT(Aα)SELECT(Aβ)=ϕ

  • αβ 至多有一个能推导出 ϵ,否则 FOLLOW(A)(SELECT(Aα)SELECT(Aβ)),导致 SELECT(Aα)SELECT(Aβ) 相交。

  • 如果 βϵ(此时 FOLLOW(A)SELECT(Aβ)),则 FIRST(α)FOLLOW(A)=ϕ;如果 αϵ(此时 FOLLOW(A)SELECT(Aα)),则 FIRST(β)FOLLOW(A)=ϕ

预测分析法

递归的预测分析法:在递归下降分析中,编写每一个非终结符对应的过程,根据预测分析表进行产生式的选择。

非递归的预测分析法:不需要为每个非终结符编写递归下降过程,而是根据预测分析表构造一个自动机,也叫表驱动的预测分析。

预测分析法实现步骤

  1. 构造文法。

  2. 改造文法:消除二义性、消除左递归、消除回溯。

  3. 求每个变量的 FIRST 集和 FOLLOW 集,从而求得每个候选式的 SELECT 集。

  4. 检查是不是 LL(1) 文法,若是,则构造预测分析表。

  5. 对于递归的预测分析,根据预测分析表为每一个非终结符编写一个过程;对于非递归的预测分析,实现表驱动的预测分析算法。

LR(0) 项目

  • 例子:SbBB

    • SbBB移进项目

    • SbBB待约项目

    • SbBB待约项目

    • SbBB归约项目

  • 待约项目可能具有等价项目,等价项目可形成项集的闭包。

LR(0) 分析表构造算法

  • 构造 G 的规范 LR(0) 项集族 C=I0,I1,...,In

  • Ii 对应状态 i。状态 i 的语法分析动作按照下面的方法决定:

    • 如果 AαaβGOTO(Ii,a)=Ij,则 ACTION[i,a]=sj

    • 如果 AαBβGOTO(Ii,B)=Ij,则 GOTO[i,B]=sj

    • 如果 AαIjAS,则对于所有 aVT{$},有 ACTION[i,a]=rjj 是产生式 Aα 的编号)。

    • 如果 SSIi,则 ACTION[i,$]=acc

  • 没有定义的所有条目都设置为 error

SLR(1) 分析表构造算法

  • 构造 G 的规范 LR(0) 项集族 C=I0,I1,...,In

  • Ii 对应状态 i。状态 i 的语法分析动作按照下面的方法决定:

    • 如果 AαaβGOTO(Ii,a)=Ij,则 ACTION[i,a]=sj

    • 如果 AαBβGOTO(Ii,B)=Ij,则 GOTO[i,B]=sj

    • ☑️ 如果 AαIjAS,则对于所有 aFOLLOW(A),有 ACTION[i,a]=rjj 是产生式 Aα 的编号)。

    • 如果 SSIi,则 ACTION[i,$]=acc

  • 没有定义的所有条目都设置为 error

LR(1) 分析表构造算法

  • 构造 G 的规范 LR(1) 项集族 C=I0,I1,...,In

  • Ii 对应状态 i。状态 i 的语法分析动作按照下面的方法决定:

    • 如果 [Aαaβ,b]IiGOTO(Ii,a)=Ij,则 ACTION[i,a]=sj

    • 如果 [AαBβ,b]IiGOTO(Ii,B)=Ij,则 GOTO[i,B]=sj

    • ☑️ 如果 [Aα,a]IiAS,则有 ACTION[i,a]=rjj 是产生式 Aα 的编号)。

    • 如果 [SS,$]Ii,则 ACTION[i,$]=acc

  • 没有定义的所有条目都设置为 error

LALR(1) 的特点

  • LALR(1) 在形式上与 LR(1) 相同。

  • LALR(1) 在大小上与 LR(0)SLR 相当。

  • LALR(1) 的分析能力介于 SLRLR(1) 之间,也就是 SLR < LALR(1) < LR(1)

  • LALR(1) 中,合并后的展望集仍为 FOLLOW 集的子集。

Updated: