自顶向下分析概述
-
自顶向下的分析
-
从分析树的**顶部(根节点)向底部(叶节点)**方向构造分析树
-
可以看成是从文法开始符号S推导出词串w的过程
-
每一步推导中,都需要做两个选择
- 替换当前句型中的哪个非终结符 那个替换
- 用该非终结符的哪个候选式进行替换 如何替换
-
-
最左推导
- 在最左推导中,总是选择每个句型的最左非终结符进行替换
- 在最左推导中,总是选择每个句型的最左非终结符进行替换
-
最右推导
- 在最右推导中,总是选择每个句型的最右非终结符进行替换
-
- 在最右推导中,总是选择每个句型的最右非终结符进行替换
-
最左推导和最右推导的唯一性
-
自顶向下的语法分析采用最左推导方式
-
总是选择每个句型的最左非终结符进行替换
-
根据输入流中的下一个终结符,选择最左非终结符的一个候选式
-
-
-
输入箭头在①时,首先文法部分 E E E出发,转换到 T — — > F T , T——>FT^{,} T——>FT, ,观察文法。 F — — > ( E ) ∣ i d F——>(E)|id F——>(E)∣id。恰好对应输入中的 i d id id,选择 F — — > i d F——>id F——>id
-
输入箭头在②时,因为 T , T^{,} T,推导中不能得到 + + +号,所以为空 ϵ \epsilon ϵ
-
对 E , E^{,} E,进行推导,发现恰好有 + + +号与之对应,选择$E’→ + T E’ $
-
输入箭头在③时,对应于 i d id id, T T T进行推导为 F T , FT^{,} FT,,之后 F — — > i d F——>id F——>id直接和 i d id id相互匹配
-
输入箭头在④时,对应于 ∗ * ∗。 T , T^{,} T, 推导☞ ∗ F T , *FT^{,} ∗FT, ,恰好和输入中的 ∗ * ∗匹配
-
之后的步骤依此类推,之后完成。
-
-
-
-
自顶向下语法分析的通用形式
- 递归下降分析(计算机实现自顶向下方式)
- 由一组过程组成,每个过程对应一个非终结符
-
-
上述情况可能会出现匹配错误 返回重新匹配的情况。需要回溯的分析器叫做不确定的分析器。回溯会影响效率,如果分析过程中,能够预测出正确的产生式,这种分析叫做预测分析。
-
- 由一组过程组成,每个过程对应一个非终结符
- 预测分析
- 预测分析是递归下降分析技术的一个特例,通过在输入中向前看固定个数(通常是一个) 符号来选择正确的A-产生式。
- 可以对某些文法构造出向前看k个输入符号的预测分析器,该类文法有时也称为** L L ( k ) LL(k) LL(k) 文法类**
- 预测分析不需要回溯,是一种确定的自顶向下分析方法
- 预测分析是递归下降分析技术的一个特例,通过在输入中向前看固定个数(通常是一个) 符号来选择正确的A-产生式。
- 递归下降分析(计算机实现自顶向下方式)
文 法 转换
并不是所有的文法都适合自顶向下分析
-
自顶向下的问题
-
-
如何直接消除左递归
-
- 把表达式化简到一般形式
-
消除直接左递归的一般形式
-
-
消除左递归是要付出代价的 —— 引进了一些非终结符和ε_产生式
-
-
-
消除间接左递归
- 代入产生式,消除产生式,化成直接左递归。直接左递归可以直接套用公式
- 代入产生式,消除产生式,化成直接左递归。直接左递归可以直接套用公式
-
消除左递归算法
--
提取左公因子
-
提取左公因子算法
-
LL(1) 文法
什么文法才能使用预测分析技术——LL(1)文法
-
S_ 文法
-
-
非终结符的后续符号集
-
- 因为 B B B 推导的 终结符 是 互不相交的,因此我们可以做出唯一的选择
-
-
-
产生式的可选集
-
- q_ 文法较为严格,因此引入功能比较强大的文法——LL(1)文法
-
-
串首终结符集
-
LL(1)文法
-
- 上述第二个条件中,最多只有一个可以推导出空集。如果两者都可以推导出空集,那两者select集均包含follow(A),这样两者select集就相交了
- 第三个条件中,当 β \beta β推导出空集时,那$\beta $ 的Select集就包含FOLLOW(A),则$\alpha $的First集中就不能包含FOLLOW(A)中的元素,否则会相交
-
LL(1)文法字符含义
- 第一个“ L”表示从左向右扫描输入
- 第二个“ L”表示产生最左推导
- “ 1”表示在每一步中只需要向前看一 个输入符号来决定语法分析器的动作
-
First集和Follow集的计算
-
计算文法符号X的 FIRST(X)
-
- 这里推导过程首先是确定右边推导式最左边的终结符。
- ②、④、⑤三者的终结符为+、*、(id、,最后加入可以推导出的空串 $\epsilon $
- 后面③可以推导出最左边的 F F F,因此把⑤的FIRST集完全加入
- ①再加入③的
- 这里推导过程首先是确定右边推导式最左边的终结符。
-
-
计算串 X 1 X 2 … X n X_1X_2\dots X_n X1X2…Xn的FIRST集合
-
- ❓ F I R S T ( X 1 ) FIRST(X_1) FIRST(X1) 可以推导出空串,但是它推导的其他终结符可以加入FIRST()集合吗?
-
-
计算非终结符 A A A 的 F O L L O W ( A ) FOLLOW(A) FOLLOW(A)
-
- 注意:这里需要计算两次
- 步骤如下:
注意:这里需要计算多次
- 步骤如下:
- 注意:这里需要计算两次
-
-
步骤如下:
- 分析①
- 文法的开始符号 E E E 本身就是这个句型的最右符号,把 KaTeX parse error: Expected '}', got 'EOF' at end of input: {}$加入 FOLLOW(E)中
- ① E , E^, E,中的所有终结符可以跟在 T T T的后面,所以我们讲 E , E^{,} E,中的所有终结符,即 F I R S T ( E , ) FIRST(E^,) FIRST(E,) 的终结符 + + + ,加入到FOLLOW(T)集中
- 又因为 E , E^, E,可以推出空串,如果 E , E^, E,可以为空,可以跟在 E E E后面的符号也可以跟在 T T T后面
- 因为 E , E^, E,是这个产生式的最后一个终结符,因此可以在E后面的元素也可以跟在 E , E^, E,中,因此可以将E中的元素添加到 E , E^, E,FOLLOW集中
- 分析②
- 因为位置和分析①类似,分析结果一样
- 分析③
- T , T^{,} T, 跟在F的后面,因此F的FIRST集合可以跟在,因此把*加入到FOLLOW(F)
- 因为 T , T^, T,中FIRST中包含了空串,因此T的FOLLOW集可以加入到F的FOLLOW集中
- 因为 T , T^, T, 是FOLLOW集合中的最后一个元素,因此把T的FOLLOW元素加入到 T , T^, T,FOLLOW中
- 分析④
- 因为位置和分析③类似,分析结果一样
- 分析⑤
- 在这里有个非终结符 E E E,因此把 ) ) )加入到 E E E中
- 分析①
-
注:
-
一个元素的FOLLOW集可以依赖于另一个元素的FOLLOW集
-
分析时,不断追加新的元素,最后需要重新分析
- 分析①
- 因为 E , E^, E,的FIRST包含出空串,因此T的FOLLOW集依赖于E的FOLLOW集合,那么需要把E中FOLLOW的 ) ) )加入FOLLOW(T)
- E , E^, E,是产生式的最后一个符号,那么它的FOLLOW集合也依赖于E,那么需要把E中FOLLOW的 ) ) )加入FOLLOW( E , E^{,} E,)
- 分析②
- 因为位置和分析①类似,分析结果一样
- 分析③
- 因为 T , T^, T,的FIRST包含出空串,因此F的FOLLOW集依赖于E的FOLLOW集合,那么需要把T中FOLLOW的 ) ) )加入FOLLOW(F)
- T , T^, T,是产生式的最后一个符号,那么它的FOLLOW集合也依赖于T,那么需要把T中FOLLOW的 ) ) )加入FOLLOW( T , T^{,} T,)
- 分析④
- 因为位置和分析③类似,分析结果一样
- 分析⑤
- 不涉及FOLLOW的添加
直到FOLLOW集合不再变化
- 分析①
-
-
计算SELECT集
-
F
I
R
S
T
FIRST
FIRST集和
F
O
L
L
O
W
FOLLOW
FOLLOW集都计算出来之后,就可以计算
S
E
L
E
C
T
SELECT
SELECT集合
-
- 计算
S
E
L
E
C
T
集
SELECT集
SELECT集的步骤
- 第一个(1)右边第一个为
T
T
T,为
T
T
T中
F
I
R
S
T
FIRST
FIRST集的终结符
- 产生式的第一个非终结符的 F I R S T FIRST FIRST集的终结符
- 第二个(2)右边为终结符 + + +,直接加入即可
- 第三个为空串,因此为 E , E^{,} E, 的 F O L L O W FOLLOW FOLLOW 元素
- 其他的以此类推
- 第一个(1)右边第一个为
T
T
T,为
T
T
T中
F
I
R
S
T
FIRST
FIRST集的终结符
- 如图所示,产生式左边相同推导的 S E L E C T SELECT SELECT集没有相交的元素
- 计算
S
E
L
E
C
T
集
SELECT集
SELECT集的步骤
-
-
F
I
R
S
T
FIRST
FIRST集和
F
O
L
L
O
W
FOLLOW
FOLLOW集都计算出来之后,就可以计算
S
E
L
E
C
T
SELECT
SELECT集合
-
预测分析表
- 可以根据
S
E
L
E
C
T
SELECT
SELECT集构建预测分析表
-
-
如箭头所示,以此类推
-
- 可以根据
S
E
L
E
C
T
SELECT
SELECT集构建预测分析表
第四章 重难点解析
-
语法分析的任务:识别句子,确定句子的类型
对于不同类型的语句,后续的语义分析器将执行不同的语义动作
-
语法分析技术分类
-
top_down
-
bottom_up
前提: CFG无二义性
-
-
-
top_down
- 通用形式:递归下降分析 模拟了自顶向下建树过程,最左推导
-
-
- 如果非终极符有多个候选键,这样需要逐个尝试,尝试失败之后会照成回溯。
-
- 通用形式:递归下降分析 模拟了自顶向下建树过程,最左推导
-
LL(1)文法
-
-
-
S E L E C T 、 F I R S T 、 F O L L O W SELECT、FIRST、FOLLOW SELECT、FIRST、FOLLOW
- 共同点:都是终结符集合,但是在 F I R S T FIRST FIRST集合中可以把$\epsilon $ 作为一个特殊的非终结符
- 不同点:操作的对象不同
-
-
top_down步骤
-
消除歧义——> 无二义性
-
文法改造
- 消除左递归 —— 不消除会进入死循环,无法top-down
- 提取左公因子 —— 如果不知道选择那个候选式会导致回溯,需要提取出来
-
LL(1)文法判定 (SELECT、FIRST、FOLLOW)——>确定性
- 确定性 和 无二义性 之间的关系
- 确定性 和 无二义性 之间的关系
-
- 满足 L L ( 1 ) LL(1) LL(1)文法可以推导出无二义性
-