Skip to main content

语法分析

文法​

正规式描述能力不够,能够定义一些简单的语言,表示给定结构的固定次数的重复或者灭有指定次数的重复,不能描述成对,配对或者嵌套的串,所以才有文法。

句型、句子、语言​

单词:满足一定规则的字符串。

句子:满足一定规则的单词序列。

语言:满足一定规则的句子集合。

推导和分析树​

推导​

推导是指通过使用给定的文法推导出目标的句子,如下例中的 id * id + id。

image-20220515131057845

推导主要有两种,分别如下:

  • 最左推导:优先从左往右进行替换。
  • 最右推导(规范推导):优先从右往左进行替换。

image-20220515131306466

分析树​

用树的形式表示句子的语法结构。

image-20220515150638809

文法的二义性​

对于文法来说,有可能会产生二义性,也就是对于一个句型来说,同一个句型能够产生两棵不同的分析树。如下图:

image-20220515162023482

image-20220515162012575

句柄、短语​

  • 句柄:最左直接短语,就是分析树中的叶子。
  • 短语:句子里面的其中一个式子。语法树中子树相对于根的短语。也就是一棵子树的叶子。

image-20220526221208337

自上而下的文法​

递归文法​

caution

消除递归记得补充上空串,在包含有递归的式子后。

image-20220515172957634

消除左递归的方法:

image-20220515183717052

蓝色框:递归重复的部分。

绿色框:递归的入口。

引入一个额外的字母 E′E',分解成两条式子转换为右递归。将左边对应颜色部分进行对应即可。

消除间接左递归:

image-20220515184133504

红色框:递归入口的部分。

绿色框:递归重复的部分。

同样引入额外的字母,将带有方框的蓝色式子的颜色方框一一对应。

求解 First 集和 Follow 集​

First 集​

  • 对于首符号为终结符 VTV_T

    对于一个产生式 α→∗abc...\alpha\stackrel{*}{\rarr} abc...,有:

    First 集为 First(α)={a}\text{First}(\alpha)=\{a\},只关注产生式产生的式子的首个符号,称为首符号集。

    tip

    可能会存在 α→∗abc...∣def...∣...∣z\alpha\stackrel{*}{\rarr} abc... | def ... | ... | z 的情况,则需要把所有的情况考虑,故 First 集为:First(α)={a,d,...,z}\text{First}(\alpha)=\{a,d,...,z\}

  • 对于首符号为非终结符 VNV_N

    对于一个产生式 α→ABC...\alpha\rarr ABC...,有:

    • 若 A→ϵA\rarr\epsilon,则 First(A)=First(A)∪{ϵ}\text{First}(A)=\text{First}(A)\cup\{\epsilon\},即当首符号为同时要求解 First(B)\text{First}(B)
    • 否则,First(α)=First(α)∪(First(A)−{ϵ})\text{First}(\alpha)=\text{First}(\alpha)\cup (\text{First}(A)-\{\epsilon\}),这个过程是多次迭代的,直到找到终结符。

Follow 集​

  1. 将 $ 加入到 Follow(S)\text{Follow}(S),其中 SS 是文法开始的符号。
  2. 若 A→αBβA\rarr \alpha B\beta,则 Follow(B)=Follow(B)∪(First(β)−{ϵ})\text{Follow}(B)=\text{Follow}(B)\cup(\text{First}(\beta)-\{\epsilon\}),即求 Follow 集只需要看产生式右侧所求符号的后继,将后继符号的 First 集加入到 Follow 集。
  3. 若 A→αBA\rarr \alpha B 或 A→αBβ, β→ϵA\rarr \alpha B\beta,\ \beta\rarr\epsilon,Follow(B)=Follow(B)∪Follow(A)\text{Follow}(B)=\text{Follow}(B)\cup\text{Follow}(A),即若产生式右侧所求符号的后继为空,则求其产生式左侧符号的 Follow 集。

LL(1)​

  1. 消除左递归、左公因子。

  2. 求每个候选式的 First 集和所有变量的 Follow 集

  3. 检查是否为 LL(1) 文法

    • 任意两个产生式 A→α∣βA\rarr \alpha|\beta满足两个条件(只要看有或的产生式即可):
      • First(α)∪First(β)=∅\text{First}(\alpha)\cup \text{First}(\beta)=\varnothing
      • 如果 B⇒ϵB\rArr\epsilon,那么则看 First(α)∪Follow(β)=∅\text{First}(\alpha)\cup \text{Follow}(\beta)=\varnothing
  4. 构造 LL(1) 分析表

    表格式为:

    image-20220527135502472

    对候选式 A→a1∣a2∣...∣anA\rarr a_1|a_2|...|a_n的右侧求其 First 集,即 First(a1∣a2∣...∣an)\text{First}(a_1|a_2|...|a_n),最后将 First 集中包含的元素按终结符的列填入到 AA 对应的行,填入元素为 A→aiA\rarr a_i。

    如果 aja_j 的 First 集中包含空串,则 Follow(A)\text{Follow}(A) 中包含的元素也填入到 AA 对应的行,填入元素为 A→ajA\rarr a_j。

  5. 分析句子

    1. 根据所给句子,从开始符出发(分析栈栈顶),从左往右开始,按照句子的符号在分析表中找对应的列,使用对应的语句。
    2. 用产生式右部替换分析栈栈顶(产生式右部的式子从右往左入栈)。
    3. 继续看栈顶查表使用对应的语句。
    4. 直到分析栈为空结束。

    image-20220526170600811

    image-20220526170617996

自下而上的文法​

构造活前缀 DFA​

image-20220527112101007

LR(0)​

  1. 增广文法,添加产生式 S′→SS'\rarr S。

  2. 构造活前缀 DFA。

  3. 判断是否为 LR(0) 文法。

  4. 构造 LR(0) 分析表。

    image-20220527112450494

  5. 基于分析表分析给定句子。

SLR(1)​

  1. 增广文法,添加产生式 S′→SS'\rarr S。

  2. 构造活前缀 DFA。

  3. 判断是否为 SLR(1) 文法。

  4. 构造 SLR(1) 分析表。(考虑 Follow 集)

    image-20220527112425060

  5. 基于分析表分析给定句子。

LR(1)​

  1. 增广文法,添加产生式 S′→SS'\rarr S。

  2. 构造活前缀 DFA。(加入第二分量)

    image-20220527150735377

  3. 判断是否为 LR(1) 文法。

  4. 构造 LR(1) 分析表。(考虑第二分量)image-20220527112407037

  5. 基于分析表分析给定句子。