符号和符号串

  • 符号:可以相互区别的记号(元素)
  • 字母表($\Sigma$):符号(元素)的非空有穷集合
  • 符号串:由字母表中的符号组成的任何有穷序列
    • 空符号串 $\varepsilon$ 是字母表 $\Sigma$ 上的符号串
    • 若 $x$ 是 $\Sigma$ 上的符号串,$a$ 是 $\Sigma$ 的元素,则 $xa$ 是 $\Sigma$ 上的符号串
    • $y$ 是 $\Sigma$ 上的符号串,当且仅当它可以由上面两个表述导出
      • 如 $\Sigma={a,b}$ 则:$\varepsilon,a,b,aa,ab,aabba,…$ 都是 $\Sigma$ 上的符号串
  • 前缀(头):移去符号串尾部的大于等于零个符号
    • $s$ 和 $\varepsilon$ 也是前缀
    • 真前缀(固有头):所有前缀的集合去除 $s$
  • 后缀(尾):移去符号串头部的大于等于零个符号
    • $s$ 和 $\varepsilon$ 也是后缀
    • 真后缀(固有尾):所有后缀的集合去除 $s$
  • 子串:移去一个头和一个尾
    • $s$ 和 $\varepsilon$ 也是子串

符号串的长度

符号串 $s$ 的长度记为 $|s|$,$|\varepsilon|=0$

符号串的连接

对于符号串 $x$ 和 $y$ 的连接:将 $y$ 写在 $x$ 之后得到 $xy$

$\varepsilon a = a\varepsilon=a$

方幂:符号串自身连接 n 次得到的符号串

$$
(ab)^n=abab…ab\ \ (ab\times n)
$$

其中,$a^0=\varepsilon$

符号串的集合

若集合 $A$ 中所有元素都是字母表 $\Sigma$ 上的符号串,则称 $A$ 为字母表 $\Sigma$ 上的符号串集合

符号串集合的乘积:$AB={xy|x\in A\ &\ y\in B}$(即做连接操作)

闭包

  • 闭包 $\Sigma^*$:$\Sigma$ 上的一切符号串(包括 $\varepsilon$)组成的集合
  • 正闭包 $\Sigma^+$: $\Sigma$ 上除了 $\varepsilon$ 外的所有符号串组成的集合

文法和语言的形式定义

规则

形如 $\alpha\rightarrow\beta$ 或 $\alpha::=\beta$ 的 $(\alpha,\beta)$ 有序对,且 $\alpha\in V^+,\beta\in V^*$,$V$ 为符号表

  • $\alpha$ 为规则的左部
  • $\beta$ 为规则的右部

别称:

  • 重写规则
  • 产生式
  • 生成式

文法

文法 $G$ 定义为四元组 $(V_N,V_T,P,S)$

  • $V_N$:非终结符集
  • $V_T$:终结符集
  • $P$:产生式(规则)集合
  • $S$:开始符号,$S\in V_N$,$S$ 必须要在一条规则的左部出现

其中:

  • $V_N\cap V_T=\phi$
  • $V=V_N\cup V_T$,即为文法 $G$ 的文法符号集合

例如:$V_N={A},V_T={0,1},P={A\rightarrow0A1,A\rightarrow 01}$,$A$ 为文法 $G$ 的开始符号

一般约定:

  • 第一条产生式的左部是开始符号
  • 用尖括号括起的是非终结符,否则为终结符
    • 或用大写字母表示非终结符;小写字母表示终结符
  • $G$ 可以表示为:$G[S]$,$S$ 为开始符号

直接推导

如果 $\alpha\rightarrow\beta$ 是文法 $G$ 的产生式,若有 $v,w$ 满足:

$$
v=\gamma\alpha\delta,w=\gamma\beta\delta\ \ and\ \ \gamma\in V^,\delta\in V^
$$

则称 $v$ 直接推导到 $w$,记作:$v\Rightarrow w$;或 $w$ 直接归约到 $v$

例:$G$: $A\rightarrow 0A1,A\rightarrow01,v=0A1,w=0011$

因为有 $A\rightarrow01,v=0A1,w=0011$ ,所以有 $v\Rightarrow w$

对于:$\varepsilon A\varepsilon\rightarrow\varepsilon 0A1\varepsilon$,可得: $A\Rightarrow 0A1 \Rightarrow 00A11$

$\Rightarrow 000A111 \Rightarrow 00001111$

(间接)推导

若存在:$v\Rightarrow w_0\Rightarrow w_1 \Rightarrow…\Rightarrow w_n=w\ (n>0)$,则称 $v$ 推导出 $w$,或 $w$ 归约到 $v$,记为 $v\Rightarrow ^+w$

若有: $v\Rightarrow ^+ w$ 或 $v=w$,则记为 $v\Rightarrow^* w$

文法的句型和句子

句型

开始符号 $S$ 经过零步或多步推导得到的任意符号串

  • 可以包含:非终结符 + 终结符
  • 也可以只含非终结符,或只含终结符

若 $S\Rightarrow^∗ \alpha$,则 $\alpha$ 是 $G$ 的一个句型

句子

从文法推导出的、只由终结符组成的句型

  • 不含任何非终结符
  • 语言中的合法串

若 $S\Rightarrow^∗\alpha\ and\ \alpha\in V_T^∗$ ​,则 $\alpha$ 是 $G$ 的一个句子

$\text{句子}\subset \text{句型}$

文法的语言

由文法 $G$ 生成的语言 $L(G)$ ,是文法 $G$ 的一切句子的集合

$$
L(G)={x|S\Rightarrow^x,x\in V_T^}
$$

  • 句子:全是终结符,没有非终结符
  • 语言:所有合法句子组成的集合

语言举例

文法 $G[S]$:
$(1)S\rightarrow aSBE; (2)S\rightarrow aBE; (3)EB\rightarrow BE ;(4)aB\rightarrow ab;(5)bB\rightarrow bb ;(6)bE\rightarrow be; (7)eE\rightarrow ee$

$$
S\Rightarrow aBE\Rightarrow abE\Rightarrow abe
$$

$$
\begin{aligned}
S\Rightarrow aSBE\ (S\rightarrow aSBE)\
\Rightarrow aaBEBE\ (S\rightarrow aBE)\
\Rightarrow aaBBEE\ (EB\rightarrow BE)\
\Rightarrow aabBEE\ (aB\rightarrow ab)\
\Rightarrow aabbEE\ (bB\rightarrow bb)\
\Rightarrow aabbeE\ (bE\rightarrow be)\
\Rightarrow aabbee\ (eE\rightarrow ee)
\end{aligned}
$$

可得 $L(G)={a^nb^ne^n|n\geq1}$

就是将所有非终结符(大写字母)推导为终结符(小写字母)

文法的等价

若 $L(G_1)=L(G_2)$ 则称文法 $G_1$ 和 $G_2$ 是等价的

文法的类型

  • 0 型文法(短语文法)
  • 1 型文法(上下文有关文法)
  • 2 型文法(上下文无关文法)
  • 3 型语法(正规/正则文法)

$$
\text{3型}\subset\text{2型}\subset\text{1型}\subset\text{0型}
$$

短语文法

$$
\alpha\rightarrow \beta
$$

  • $\alpha$ 至少含一个非终结符
  • $\beta$ 任意(可以为空)

几乎没有限制

上下文有关文法

必须满足

$$
|\alpha|\leq|\beta|
$$

不能变短

上下文无关文法

$$
A\rightarrow \beta
$$

  • 左部必须是单个非终结符
  • 右部任意(需要满足 1 型的长度条件)

正规文法

右线性:

$$
A\rightarrow aB,A\rightarrow a
$$

左线性:

$$
A\rightarrow Ba,A\rightarrow a
$$

只能线性展开,不能嵌套递归

上下文无关文法及其语法树

上下文无关文法(Context-Free Grammar,CFG)是最重要的文法类型,适合描述程序设计语言的大部分语法结构。

为什么叫”上下文无关”

在上下文无关文法中,产生式形如 $A\rightarrow\beta$:

  • 左部必须是单个非终结符 $A$
  • $A$ 的推导不依赖于它周围的符号(即”上下文”)
  • 无论 $A$ 出现在什么位置,都可以用 $\beta$ 替换

相比之下,上下文有关文法的产生式可能是 $\alpha A\gamma\rightarrow\alpha\beta\gamma$,表示只有当 $A$ 的左边是 $\alpha$、右边是 $\gamma$ 时才能替换,这就依赖于”上下文”。

语法树(推导树/分析树)

语法树是推导过程的图形化表示,能够清晰地展示句型的结构。

语法树的定义

对于文法 $G=(V_N,V_T,P,S)$,一棵语法树满足:

  1. 根节点:标记为开始符号 $S$
  2. 内部节点:标记为非终结符 $V_N$ 中的符号
  3. 叶节点:标记为终结符 $V_T$ 中的符号或 $\varepsilon$
  4. 父子关系:如果有产生式 $A\rightarrow X_1X_2…X_n$,则节点 $A$ 有 $n$ 个子节点,从左到右标记为 $X_1,X_2,…,X_n$

语法树的特点

  • 叶节点从左到右连接起来,就是一个句型
  • 如果所有叶节点都是终结符,则这个句型是一个句子
  • 同一个句型可能有多棵不同的语法树(对应不同的推导顺序)

语法树示例

文法 $G[E]$:
$E\rightarrow E+E$ > $E\rightarrow E*E$ > $E\rightarrow (E)$ > $E\rightarrow id$

对于句子 $id+id*id$,可以有以下推导:

推导 1

$$
E\Rightarrow E+E\Rightarrow id+E\Rightarrow id+EE\Rightarrow id+idE\Rightarrow id+id*id
$$

对应的语法树:

        E
       /|\
      E + E
      |  /|\
     id E * E
        |   |
       id  id

推导 2

$$
E\Rightarrow EE\Rightarrow E+EE\Rightarrow id+EE\Rightarrow id+idE\Rightarrow id+id*id
$$

对应的语法树:

        E
       /|\
      E * E
     /|\  |
    E + E id
    |   |
   id  id

这两棵语法树的叶节点序列都是 $id+idid$,但*结构不同,导致运算优先级不同

而这样能够构建出不同语法树的文法,称其为具有二义性

最左推导和最右推导

为了规范推导过程,我们定义两种特殊的推导方式。

最左推导

在推导的每一步,总是替换最左边的非终结符

记作:$\Rightarrow_{lm}$(leftmost derivation)

最右推导(规范推导)

在推导的每一步,总是替换最右边的非终结符

记作:$\Rightarrow_{rm}$(rightmost derivation)

示例

对于文法 $G[E]$:$E\rightarrow E+T\ |\ T$,$T\rightarrow T*F\ |\ F$,$F\rightarrow(E)\ |\ id$

句子 $id+id*id$ 的最左推导:

$$
\begin{aligned}
E&\Rightarrow_{lm} E+T \
&\Rightarrow_{lm} T+T \
&\Rightarrow_{lm} F+T \
&\Rightarrow_{lm} id+T \
&\Rightarrow_{lm} id+TF \
&\Rightarrow_{lm} id+F
F \
&\Rightarrow_{lm} id+idF \
&\Rightarrow_{lm} id+id
id
\end{aligned}
$$

句子 $id+id*id$ 的最右推导:

$$
\begin{aligned}
E&\Rightarrow_{rm} E+T \
&\Rightarrow_{rm} E+TF \
&\Rightarrow_{rm} E+T
id \
&\Rightarrow_{rm} E+Fid \
&\Rightarrow_{rm} E+id
id \
&\Rightarrow_{rm} T+idid \
&\Rightarrow_{rm} F+id
id \
&\Rightarrow_{rm} id+id*id
\end{aligned}
$$

注意:虽然推导顺序不同,但它们对应的语法树是同一棵

二义性文法

定义

如果文法 $G$ 的某个句子存在两棵不同的语法树(或有两个不同的最左推导,或有两个不同的最右推导),则称文法 $G$ 是二义性的(ambiguous)。

二义性的判定

  • 判定一个文法是二义性的:只需找到一个句子,它有两棵不同的语法树
  • 判定一个文法是无二义性的:没有通用算法!(不可判定问题)

二义性文法的例子

文法 $G[E]$:$E\rightarrow E+E\ |\ E*E\ |\ (E)\ |\ id$

对于句子 $id+idid$,前面已经展示了两棵不同的语法树,所以这是一个*二义性文法

消除二义性

二义性文法往往不符合我们的语义要求(如运算优先级),需要改写文法消除二义性。

改写方法引入多层非终结符,将优先级编码到文法结构中

改写后的无二义性文法:

$$
\begin{aligned}
E&\rightarrow E+T\ |\ T \
T&\rightarrow T*F\ |\ F \
F&\rightarrow (E)\ |\ id
\end{aligned}
$$

这个文法保证了:

  • $*$ 的优先级高于 $+$
  • 同级运算符左结合
  • 每个句子只有唯一的语法树

悬挂 else 问题

另一个经典的二义性例子:

文法 $G[S]$:

$$
\begin{aligned}
S&\rightarrow \text{if}\ E\ \text{then}\ S \
S&\rightarrow \text{if}\ E\ \text{then}\ S\ \text{else}\ S \
S&\rightarrow \text{other}
\end{aligned}
$$

对于句子:if E1 then if E2 then S1 else S2

有两种理解:

  1. if E1 then (if E2 then S1 else S2) —— else 匹配内层 if
  2. if E1 then (if E2 then S1) else S2 —— else 匹配外层 if

消除方法:规定 else 总是与最近的未匹配的 if 匹配

改写文法:

$$
\begin{aligned}
S&\rightarrow M\ |\ U \
M&\rightarrow \text{if}\ E\ \text{then}\ M\ \text{else}\ M\ |\ \text{other} \
U&\rightarrow \text{if}\ E\ \text{then}\ S \
U&\rightarrow \text{if}\ E\ \text{then}\ M\ \text{else}\ U
\end{aligned}
$$

其中 $M$ 表示匹配的语句(matched),$U$ 表示未匹配的语句(unmatched)。

句型的分析

句型分析是编译器语法分析器的核心任务:给定一个符号串,判断它是否是文法的句型,如果是,构造出它的语法树。

短语、直接短语和句柄

这些概念用于描述句型的结构,是自下而上分析的理论基础。

短语

设有文法 $G[S]$,$\alpha$ 是 $G$ 的一个句型,如果有:

$$
S\Rightarrow^*\beta A\delta\ \text{且}\ A\Rightarrow^+\gamma
$$

其中 $\alpha=\beta\gamma\delta$,则称 $\gamma$ 是句型 $\alpha$ 相对于非终结符 $A$ 的短语

通俗理解:短语是语法树中某个子树的所有叶节点连起来的符号串。

直接短语

如果有 $A\Rightarrow\gamma$(一步推导),则称 $\gamma$ 是句型 $\alpha$ 相对于非终结符 $A$ 的直接短语

通俗理解:直接短语是语法树中某个子树高度为 2(根到叶只有一步)的所有叶节点连起来的符号串。

句柄

句型最左边的直接短语称为该句型的句柄

通俗理解:句柄是我们在自下而上分析时,下一步应该归约的部分

示例

文法 $G[E]$:

$$
\begin{aligned}
E&\rightarrow E+T\ |\ T \
T&\rightarrow T*F\ |\ F \
F&\rightarrow (E)\ |\ id
\end{aligned}
$$

句型 $id_1*id_2+id_3$ 的语法树:

          E
         /|\
        E + T
		|   |
		T	F
	   /|\  |
	  T * F id3
	  |   |
	  F  id2
	  |
	 id1
  • 短语
    • $F: id_1,id_2,id_3$
    • $T:id_1, id_3, id2*id3$
    • $E: id_1id_2, id_1+id_2id_3$
  • 直接短语:$id_1$($F\rightarrow id$)、$id_2$($F\rightarrow id$)、$id_3$($F\rightarrow id$)
  • 句柄:$id_1$(最左边的直接短语)

总结:就是选取一个结点,其子树的叶子结点组合即为一个短语;如果选取结点与其叶子结点相邻,则为直接短语

自上而下的分析方法

从开始符号 $S$ 出发,尝试推导出输入串,使用最左推导

基本思想

  1. 从文法的开始符号 $S$ 开始
  2. 每次选择一个非终结符进行推导
  3. 选择合适的产生式进行替换
  4. 最终推导出输入串

面临的问题

问题 1:回溯问题

当有多个产生式可选时,可能需要回溯(backtracking)。

例如,文法 $G[S]$:$S\rightarrow aAd$,$A\rightarrow ab\ |\ a$

输入串:$aad$

  • 尝试 $A\rightarrow ab$:$S\Rightarrow aAd\Rightarrow aabd$ ❌ 失败,需要回溯
  • 尝试 $A\rightarrow a$:$S\Rightarrow aAd\Rightarrow aad$ ✓ 成功

回溯会严重影响效率!

问题 2:左递归问题

如果文法中有左递归(如 $A\rightarrow A\alpha$),自上而下分析会陷入无限循环。

例如:$E\rightarrow E+T$ 是左递归的,从 $E$ 出发会不断推导 $E\Rightarrow E+T\Rightarrow E+T+T\Rightarrow…$

解决方法

  1. 消除左递归:将左递归改写为右递归或使用 $\varepsilon$ 产生式
  2. 提取公共左因子:减少回溯
  3. 构造预测分析表:使用 FIRST 和 FOLLOW 集合(后续章节详细讲解)

自下而上的分析方法

从输入串出发,逐步归约到开始符号 $S$,相当于最右推导的逆过程

基本思想

  1. 从输入串开始
  2. 找到句柄(最左边的直接短语)
  3. 用相应的非终结符替换句柄(归约)
  4. 重复步骤 2-3,直到归约到开始符号 $S$

这个过程也叫移进-归约分析(shift-reduce parsing)。

示例

文法 $G[E]$:$E\rightarrow E+T\ |\ T$,$T\rightarrow T*F\ |\ F$,$F\rightarrow(E)\ |\ id$

分析 $id_1+id_2*id_3$:

步骤 符号栈 输入串 动作
1 $ $id_1+id_2*id_3$ 移进 $id_1$
2 $id_1$ $+id_2*id_3$ 归约 $F\rightarrow id$
3 $F$ $+id_2*id_3$ 归约 $T\rightarrow F$
4 $T$ $+id_2*id_3$ 归约 $E\rightarrow T$
5 $E$ $+id_2*id_3$ 移进 $+$
6 $E+$ $id_2*id_3$ 移进 $id_2$
7 $E+id_2$ $*id_3$ 归约 $F\rightarrow id$
8 $E+F$ $*id_3$ 归约 $T\rightarrow F$
9 $E+T$ $*id_3$ 移进 $*$
10 $E+T*$ $id_3$ 移进 $id_3$
11 $E+T*id_3$ $ 归约 $F\rightarrow id$
12 $E+T*F$ $ 归约 $T\rightarrow T*F$
13 $E+T$ $ 归约 $E\rightarrow E+T$
14 $E$ $ 接受

优势

  • 不需要回溯(对于 LR 文法)
  • 可以处理更广泛的文法
  • 是现代编译器的主流方法

句型分析的有关问题

1. 句型的分析是可判定的吗?

:对于上下文无关文法,句型的分析是可判定的。存在多项式时间算法(如 CYK 算法),但实际编译器中使用更高效的 LL 和 LR 分析方法。

2. 如何选择分析方法?

分析方法 适用文法 优点 缺点
LL(k) LL(k) 文法 实现简单,易于理解 文法限制较多,不能处理左递归
LR(k) LR(k) 文法 识别能力强,接近所有上下文无关文法 实现复杂,分析表较大
LALR(k) LALR(k) 文法 折中方案,yacc/bison 使用 某些情况下会有冲突

3. 文法的改写

有时需要改写文法以满足特定分析方法的要求:

  • 消除左递归:将 $A\rightarrow A\alpha\ |\ \beta$ 改写为 $A\rightarrow\beta A’$,$A’\rightarrow\alpha A’\ |\ \varepsilon$
  • 提取左公因子:将 $A\rightarrow\alpha\beta_1\ |\ \alpha\beta_2$ 改写为 $A\rightarrow\alpha A’$,$A’\rightarrow\beta_1\ |\ \beta_2$
  • 消除二义性:如前面的表达式文法改写

有关文法实际应用

有关文法实用限制

在实际应用中,我们通常对文法施加一些限制,以便构造高效的语法分析器。

1. 无二义性

要求:文法必须是无二义性的。

原因:二义性文法会导致同一个句子有多种解释,无法确定唯一的语法树。

实践:如果原始文法有二义性,需要改写或引入优先级、结合性规则。

2. 不含左递归(针对 LL 分析)

要求:文法不能有形如 $A\Rightarrow^+ A\alpha$ 的推导。

原因:左递归会导致自顶向下分析器陷入无限循环。

消除方法

直接左递归:$A\rightarrow A\alpha\ |\ \beta$

改写为:

$$
\begin{aligned}
A&\rightarrow\beta A’ \
A’&\rightarrow\alpha A’\ |\ \varepsilon
\end{aligned}
$$

3. 提取左公因子(针对 LL 分析)

要求:减少需要向前查看的符号数量。

原因:左公因子会导致难以决策使用哪个产生式。

提取方法

原文法:$A\rightarrow\alpha\beta_1\ |\ \alpha\beta_2\ |\ …\ |\ \alpha\beta_n\ |\ \gamma$

改写为:

$$
\begin{aligned}
A&\rightarrow\alpha A’\ |\ \gamma \
A’&\rightarrow\beta_1\ |\ \beta_2\ |\ …\ |\ \beta_n
\end{aligned}
$$

4. LL(k) 或 LR(k) 条件

LL(k):向前看 $k$ 个符号就能决定使用哪个产生式
LR(k):向前看 $k$ 个符号就能决定何时归约

实际中,$k=1$ 就足够了(LL(1)、LR(1)、LALR(1))。

上下文无关文法中的 $\varepsilon$ 规则

$\varepsilon$ 规则(也叫空产生式)形如 $A\rightarrow\varepsilon$,表示非终结符 $A$ 可以推导出空串。

$\varepsilon$ 规则的作用

  1. 表示可选成分

例如:C 语言中函数的参数列表可以为空

$$
\text{params}\rightarrow\text{param-list}\ |\ \varepsilon
$$

  1. 简化文法描述

例如:标识符列表(至少一个)

$$
\begin{aligned}
\text{id-list}&\rightarrow\text{id}\ \text{id-list}’ \
\text{id-list}’&\rightarrow\text{id}\ \text{id-list}’\ |\ \varepsilon
\end{aligned}
$$

可空符号(NULLABLE)

如果 $A\Rightarrow^\varepsilon$,则称 $A$ 是*可空的(nullable)。

判定方法(不动点算法):

  1. 初始化:所有有 $A\rightarrow\varepsilon$ 的 $A$ 是可空的
  2. 重复:如果 $A\rightarrow X_1X_2…X_n$,且 $X_1,…,X_n$ 都是可空的,则 $A$ 是可空的
  3. 直到不再有新的可空符号加入

消除 $\varepsilon$ 规则

有些分析方法不允许 $\varepsilon$ 规则(除了 $S\rightarrow\varepsilon$),需要消除。

消除方法

  1. 找出所有可空符号
  2. 对于每个产生式 $A\rightarrow\alpha$,如果 $\alpha$ 中含有可空符号 $B$,则增加一个产生式,将 $B$ 删除
  3. 重复步骤 2,直到 $\alpha$ 中的所有可空符号组合都被考虑
  4. 删除所有 $A\rightarrow\varepsilon$ 规则(除非 $A$ 是开始符号)

示例

原文法:

$$
\begin{aligned}
S&\rightarrow aAB \
A&\rightarrow bA\ |\ \varepsilon \
B&\rightarrow cB\ |\ \varepsilon
\end{aligned}
$$

$A$ 和 $B$ 都是可空的。

对 $S\rightarrow aAB$:

  • 删除 $A$:$S\rightarrow aB$
  • 删除 $B$:$S\rightarrow aA$
  • 删除 $A$ 和 $B$:$S\rightarrow a$

消除后的文法:

$$
\begin{aligned}
S&\rightarrow aAB\ |\ aA\ |\ aB\ |\ a \
A&\rightarrow bA\ |\ b \
B&\rightarrow cB\ |\ c
\end{aligned}
$$

注意事项

  1. 消除 $\varepsilon$ 规则可能会增加产生式数量
  2. 如果开始符号 $S$ 是可空的,且 $S$ 出现在其他产生式右部,需要特殊处理:
    • 引入新的开始符号 $S’$
    • 添加 $S’\rightarrow S\ |\ \varepsilon$

本章小结

本章介绍了形式语言理论的基础概念:

  • 文法:用产生式描述语言的语法结构
  • 推导与归约:句子的生成和识别过程
  • 文法类型:从 3 型(正规)到 0 型(短语),其中上下文无关文法最重要
  • 语法树:推导过程的图形化表示,直观展示句子结构
  • 二义性:同一句子有多棵语法树,需要改写文法消除
  • 句型分析:自顶向下和自底向上两种基本方法
  • 文法改写:消除左递归、提取左公因子、消除 $\varepsilon$ 规则等

掌握这些概念是学习后续词法分析、语法分析等章节的基础。