自底向上——算符优先分析

1521 字
8 分钟
自底向上——算符优先分析
Warning

含AI生成内容

第五章 自底向上——算符优先分析 · 知识点详解#

🔴 核心(必背/必算) 🟡 理解(会说清) 🟢 了解(有印象) 本章性质:计算大题(约 20 分),短语 + 优先表 + 分析过程。


一、自底向上分析基础(🟡 理解)#

  • 自底向上 = 归约:把产生式右部(RHS)替换为左部(LHS),从叶子向根构造语法树。
  • 移进-归约法:用一个栈存文法符号。
    • 移进:把一个终结符推进栈。
    • 归约:把栈顶的可归约串弹出,用相应产生式左部的非终结符压入。
    • 最终栈中只剩 # 和开始符 S,则输入串是句子;否则报错。
  • 核心问题:如何找句柄(可归约串)。不同找法 → 不同分析方法(简单优先、算符优先、LR)。

规范归约#

最右推导的逆过程:每步归约句型的句柄,得到规范归约序列 αₙ⇒αₙ₋₁⇒…⇒α₁=S


二、短语相关概念(🔴 核心,名词解释高频)#

αγβ 是句型:

  • 短语S⇒*αAβA⇒⁺γ,则 γ 是相对 A 的短语。
  • 直接短语S⇒*αAβA⇒γ(一步),则 γ 是相对 A→γ 的直接短语。
  • 句柄:最左直接短语。
  • 素短语(Prime Phrase):满足以下三条的短语——
    1. 是一个短语;
    2. 至少包含一个终结符
    3. 除自身外不再包含其他素短语
  • 最左素短语:句型中处于最左边的素短语。

🧮 例题(务必练熟,5 项都写)#

文法 E→E+T|T,T→T*F|F,F→(E)|i,句型 T+T*F

  • 短语TT*FT+T*F
  • 直接短语T*F(也可含 T 由 T→…)
  • 句柄:最左直接短语
  • 素短语T*Fi(含终结符且不含其他素短语)
  • 最左素短语T*F

补充例:句型 F↑P+T*(E+T) 中 —— 短语含 F↑PT*(E+T) 等;直接短语 F↑PE+T;句柄 F↑P;素短语 F↑PE+T;最左素短语 F↑P


三、算符文法 OG 与算符优先文法 OPG(🟡 理解)#

算符文法 OG(Operator Grammar)#

文法 G 中没有形如 U→…VW…(两个非终结符相邻)的规则,则 G 是算符文法。

  • 性质 1:任何句型都不含两个相邻的非终结符。
  • 性质 2:若 AbbA 出现在句型中,则含 b 的短语必含 A。

算符优先关系(只看终结符之间,有次序#

  • a = b:存在规则 A→…ab…A→…aBb…
  • a < b:存在规则 A→…aB…,且 B⇒⁺b…B⇒⁺Cb…(a 优先级低于 b)。
  • a > b:存在规则 A→…Bb…,且 B⇒⁺…aB⇒⁺…aC(a 优先级高于 b)。

⚠️ <=> 表示归约的先后,与数学大小无关,且有方向(a<b 与 b<a 不同)。

算符优先文法 OPG(Operator Precedence Grammar)#

一个不含 ε 规则的 OG,若任意两个终结符间至多只有一种优先关系,则 G 是算符优先文法。

结论:OPG 是无二义的。


四、构造算符优先关系表(🔴 核心)#

FIRSTVT / LASTVT#

  • FIRSTVT(A) = { b | A⇒⁺b… 或 A⇒⁺Bb…, b∈V_T, B∈V_N } —— A 往下推导能露出的**第一个算符(终结符)**集合。
  • LASTVT(A) = { a | A⇒⁺…a 或 A⇒⁺…aB, a∈V_T, B∈V_N } —— A 往下推导能露出的**最后一个算符(终结符)**集合。

构造关系表的规则#

  1. 先算每个非终结符的 FIRSTVT、LASTVT。
  2. 填优先关系:
    • A→…aB…:对 FIRSTVT(B) 中每个 b,置 a < b
    • A→…Ba…:对 LASTVT(B) 中每个 b,置 b > a
    • A→…ab…A→…aBb…:置 a = b
  3. 补界符:
    • 对 FIRSTVT(S) 中每个 b,置 # < b
    • 对 LASTVT(S) 中每个 a,置 a > #
    • # = #

🧮 例(表达式文法)#

E→E+T|T,T→T*F|F,F→(E)|i

非终结符FIRSTVTLASTVT
E{+,*,(,i}{+,*,),i}
T{*,(,i}{*,),i}
F{(,i}{),i}

由此可填出 +<**>+(=)#<+/*/(/i+/*/)/i># 等关系。


五、算符优先分析过程(🔴 核心)#

最左素短语的识别#

算符优先文法的句型可写成 # N₁a₁N₂a₂…NₙaₙNₙ₊₁ #。最左素短语是满足下式的最左子串:

aᵢ₋₁ < aᵢ ≐ aᵢ₊₁ ≐ … ≐ aⱼ₋₁ ≐ aⱼ > aⱼ₊₁

(即被 < 开头、> 结尾夹住的一段,中间是 =)。

分析算法(移进-归约)#

  1. 栈初始化为 #
  2. 栈顶终结符与当前输入符比较:
    • <=移进输入符。
    • >:说明找到最左素短语的尾,向栈内找到相同优先关系的串归约(非终结符不影响识别,可用任意 N 代替)。
  3. 两终结符间无优先关系 → 出错。
  4. 读到 # 且栈中只剩 #N 时,接受

🧮 分析 i+i# 过程#

关系当前符输入动作
1#<i+i#移进
2#i>+i#归约(F→i)
3#N<+i#移进
4#N+<i#移进
5#N+i>#归约
6#N+N>#归约
7#N=#接受

六、优先函数(🔴 核心 · Floyd 算法)#

目的#

用两个整数函数 f、g 代替优先矩阵,把存储从 (n+1)² 降到 2(n+1)。

定义#

  • a=b ⟹ f(a)=g(b)
  • a<b ⟹ f(a)<g(b)
  • a>b ⟹ f(a)>g(b)

构造(Floyd 算法)#

  1. 对每个终结符 a(含 #),令 f(a)=g(a)=1
  2. 逐行扫描优先矩阵,反复执行:
    • a>b 且 f(a)≤g(b) ⟹ f(a)=g(b)+1;
    • a<b 且 f(a)≥g(b) ⟹ g(b)=f(a)+1;
    • a=b 且 f(a)≠g(b) ⟹ 令二者取 max(相等)。
  3. 迭代到收敛;若出现 >2n 的值,说明不存在优先函数

性质#

  • 优先函数不唯一(各值同加常数关系不变)。
  • 存在优先关系的矩阵不一定存在优先函数。
  • 缺点:无优先关系的空格(出错位置)用函数无法体现,而矩阵可置出错标记。

⚠️ 易错点汇总#

  • 素短语必须至少含一个终结符(纯非终结符的短语不是素短语)。
  • 算符优先去掉了单非终结符归约(如 T→F),可能把错句子误判为正确(最大缺点)。
  • 优先关系有方向a<bb<a 不同,别写反。
  • OPG 是无二义的;OG 不一定。

📝 常考题型#

  • 名词解释:句柄、素短语、最左素短语、语法树。
  • 给文法句型求 5 种短语(短语/直接短语/句柄/素短语/最左素短语)。
  • 求 FIRSTVT/LASTVT,构造算符优先关系表(写步骤)。
  • 对输入串(如 a↑a+a*a)写算符优先分析过程(栈/关系/输入/动作)。

🟢 了解#

  • 简单优先分析法:按所有文法符号(含非终结符)间优先关系确定句柄;缺点效率低、只适用简单优先文法、一般语言不满足。
  • 简单优先文法两条件:任两符号最多一种优先关系;任两产生式无相同右部。
  • 算符优先分析法适用范围:表达式的语法分析。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

自底向上——算符优先分析
https://lingluoa.icu/posts/编译原理/知识点-第5章-算符优先分析/
作者
lingluoa
发布于
2026-07-04
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
lingluoa
Hello, I'm lingluoa.
公告
欢迎来到我的博客!不定期更新中。
文章目录
标签
站点统计
文章
53
分类
9
标签
75
总字数
175,771
运行时长
0
最后活动
0 天前
站点信息
构建平台
ESA Pages
博客版本
Firefly v6.15.6
文章许可
CC BY-NC-SA 4.0