自顶向下语法分析
1186 字
6 分钟
自顶向下语法分析
Warning
含AI生成内容
第四章 自顶向下语法分析 · 知识点详解
🔴 核心(必背/必算) 🟡 理解(会说清) 🟢 了解(有印象) 本章性质:计算大题(约 20 分),改文法 + 判 LL(1) + 预测分析。
一、语法分析概述(🟡 理解)
- 任务:检查扫描器输出的单词序列是否是该文法的句子。
- 输入:单词符号序列;输出:分析树;出错时定位并续编译。
- 两大类方法:
- 自顶向下:确定的(递归下降法、预测分析法)、不确定的(带回溯)。
- 自底向上:算符优先、LR 分析(LR(0)、SLR(1)、LR(1)、LALR(1))。
- LL 文法用递归下降/预测分析、多用于手工实现;LR 文法用 LR 分析、多用于自动生成。
自顶向下基本思想
面向目标,寻找输入串的最左推导:从开始符(根)出发,按最左推导顺序,试图根据当前输入单词选择产生式,逐步构造分析树。
二、FIRST / FOLLOW / SELECT 集(🔴 核心)
FIRST(α)——首符号集
FIRST(α) = { a | α ⇒* aβ, a∈V_T },若 α⇒*ε 则 ε∈FIRST(α)。
计算规则:
X∈V_T:FIRST(X)={X}。X→a…(a∈V_T):a∈FIRST(X)。X→ε:ε∈FIRST(X)。X→Y₁Y₂…Yₙ:- 把 FIRST(Y₁)−{ε} 加入 FIRST(X);
- 若 Y₁⇒*ε,再加 FIRST(Y₂)−{ε};依次类推;
- 若 Y₁…Yₙ 全部能⇒ε,则把 ε 也加入 FIRST(X)。
- 反复迭代直到所有 FIRST 集不再变化。
FOLLOW(A)——后继符号集
FOLLOW(A) = { a | S ⇒* …Aa…, a∈V_T };若 S⇒*…A,则 #∈FOLLOW(A)。
计算规则(对所有出现在右部的非终结符反复迭代):
#∈FOLLOW(S)(S 为开始符,# 为结束符)。A→αBβ且 β 不能⇒ε:FOLLOW(B) ⊇ FIRST(β)。A→αB:FOLLOW(B) ⊇ FOLLOW(A)。A→αBβ且 β⇒*ε:FOLLOW(B) ⊇ (FIRST(β)−{ε}) ∪ FOLLOW(A)。
注意:FOLLOW 集中永远不含 ε(要么是终结符,要么是 #)。
SELECT(A→α)——选择集
- α 不能⇒ε:
SELECT(A→α) = FIRST(α)。 - α ⇒*ε:
SELECT(A→α) = (FIRST(α)−{ε}) ∪ FOLLOW(A)。
三、LL(1) 文法(🔴 核心)
含义
- 第一个 L:从左到右扫描输入串。
- 第二个 L:生成最左推导。
- 1:向前看 1 个符号即可确定用哪个产生式。
判定充要条件
对每个非终结符 A 的任意两个不同候选式 A→α | β:
SELECT(A→α) ∩ SELECT(A→β) = ∅(且 α、β 不能同时⇒ε)。
判别步骤
- 列出各非终结符能否⇒ε。
- 计算 FIRST、FOLLOW 集。
- 计算各规则 SELECT 集。
- 检查同一左部各规则的 SELECT 集是否两两不相交——全不相交则为 LL(1) 文法。
🧮 判定例(表达式文法 G[E] 是 LL(1))
E→TE' E'→+TE'|ε T→FT' T'→*FT'|ε F→(E)|i- SELECT(E’→+TE’)={+},SELECT(E’→ε)={#,)},交集=∅ ✓
- SELECT(T’→FT’)={},SELECT(T’→ε)={+,#,)},交集=∅ ✓
- SELECT(F→(E))={(},SELECT(F→i)={i},交集=∅ ✓
- 故 G[E] 是 LL(1) 文法。
四、非 LL(1) → LL(1) 的改造(🔴 核心)
1. 消除左递归
直接左递归 A→Aα|β:
A → βA'A' → αA'|ε一般式 A→Aα₁|…|Aαₙ|β₁|…|βₘ ⟹
A → β₁A'|…|βₘA'A' → α₁A'|…|αₙA'|ε间接左递归:先按非终结符排序,用代入法把间接左递归化成直接左递归,再消除,最后删除多余产生式。
例:
S→Qc|c, Q→Rb|b, R→Sa|a,按 S,Q,R 排序,代入得R→Rbca|bca|ca|a,消直接左递归得R→bcaM|caM|aM, M→bcaM|ε。
2. 提取左公共因子
A→αβ|αγ ⟹
A → αA'A' → β|γ一般式 A→αβ₁|…|αβₙ|γ₁|…|γₘ ⟹
A → αA'|γ₁|…|γₘA' → β₁|…|βₙ提取后可能出现不可达的多余产生式,必须删除。
五、预测分析法(🔴 核心)
预测分析器三部分
- 预测分析表(矩阵) M[A,a]
- 先进后出栈(分析栈,存语法符号)
- 预测分析程序(总控)
构造预测分析表 M[A,a]
对产生式 A→α,凡 a∈SELECT(A→α),就把 →α 填入 M[A,a]。所有空格填 error。
表达式文法 G[E] 的预测分析表:
| i | + | * | ( | ) | # | |
|---|---|---|---|---|---|---|
| E | →TE’ | →TE’ | ||||
| E’ | →+TE’ | →ε | →ε | |||
| T | →FT’ | →FT’ | ||||
| T’ | →ε | →*FT’ | →ε | →ε | ||
| F | →i | →(E) |
预测分析算法
初始化:#、S 进栈(# 在底,S 在顶)do { X = 栈顶符号;a = 当前输入符号; if (X∈V_T ∪ {#}) { if (X==a) { 若 X≠#,弹栈并前移输入指针; } else error(); } else { // X 是非终结符 if (M[X,a]==Y₁Y₂…Yₖ) { 弹出 X; 把 Yₖ…Y₂Y₁ 逆序压栈; } else error(); }} while (X≠#)🧮 分析 i+i*i# 过程(片段)
| 步 | 分析栈 | 剩余输入 | 所用规则 |
|---|---|---|---|
| 1 | #E | i+i*i# | E→TE’ |
| 2 | #E’T | i+i*i# | T→FT’ |
| 3 | #E’T’F | i+i*i# | F→i |
| 4 | #E’T’i | i+i*i# | 匹配 i |
| … | … | … | … |
| 17 | # | # | 成功接受 |
⚠️ 易错点汇总
- α⇒*ε 时 SELECT 一定要并上 FOLLOW(A),别只写 FIRST。
- FOLLOW 集不含 ε(只含终结符和 #)。
- 消左递归 / 提公因子后常出现不可达(多余)产生式,必须删除。
- 递归下降要求文法必须是 LL(1);直接左递归会导致死循环。
- 预测分析压栈要逆序(右部最左符号最后压,处于栈顶)。
📝 常考题型
- 改写文法使其适合自顶向下(消左递归 + 提公因子)。
- 判断改写后是否 LL(1)(写依据:SELECT 交集为空)。
- 构造预测分析表。
- 对输入串(如
i+i*i#)写出预测分析过程。
🟢 了解
- 递归下降法:为每个非终结符写一个递归子程序;用 EBNF(
{α}=α*、[α]可选)画语法图后实现。优点直观易扩充;缺点效率低、要求 LL(1)、难自动生成。 - 引起回溯的三个原因:右部 FIRST 相交、能推空且 FOLLOW 与其他右部 FIRST 相交、含左递归。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
自底向上——LR 分析
编译原理编译原理知识点(考试向)
2
自底向上——算符优先分析
编译原理编译原理知识点(考试向)
3
词法分析
编译原理编译原理知识点(考试向)
4
复习提纲
编译原理编译原理复习提纲(考试向)
5
编译原理知识点
编译原理编译原理知识点(考试向)
随机文章随机推荐










