编译原理基础:FIRST 集合与 FOLLOW 集合的构造与差异

编译原理基础:FIRST 集合与 FOLLOW 集合的构造与差异

嗨!学编译原理时,FIRST 集合和 FOLLOW 集合是不是让你有点晕?别急,今天我们要把它们讲清楚,先用一个表格对比它们的区别,再一步步教你怎么构造它们。这篇博客是为基础一般的同学设计的,尽量简单又不失严谨,走起!

FIRST vs FOLLOW:一表格看懂差异

特性 FIRST 集合 FOLLOW 集合
关心啥 推导字符串的"开头" 非终结符"后面紧跟"的东西
收集啥 第一个终结符(或 ε) 后面紧跟的终结符(或 $)
位置 看"前" 看"后"
例子 FIRST(T) = { id, ( } FOLLOW(T) = { +, ;, ) }
用途 决定推导从哪开始 决定推导完后下一步是啥

简单说:FIRST 是"开头侦察兵",FOLLOW 是"后续导航员",它们都只关心终结符(代码里实实在在的符号),不直接管非终结符(推导的中间步骤)。

FIRST 集合:开头有哪些可能?

感性理解

FIRST 集合就像猜一个故事的开头。比如你在写代码,编译器得知道某个部分(比如表达式)可能以什么打头------是 "id"(变量名)?还是 "("(括号)?FIRST 集合把这些"可能的开头"列出来,帮编译器找方向。

形式化表达

FIRST(A) 是非终结符 A 能推导出的所有字符串的第一个终结符的集合。如果 A 能推导出空串 ε,则 ε ∈ FIRST(A)。

构造方法

  1. 终结符:FIRST(a) = { a }。
  2. 空串:FIRST(ε) = { ε }。
  3. 非终结符 A (A → X1 X2 ... Xn):
    • 如果 X1 是终结符,加到 FIRST(A)。
    • 如果 X1 是非终结符:
      • 把 FIRST(X1)(去掉 ε)加到 FIRST(A)。
      • 如果 X1 能推 ε,继续看 X2,依次类推。
      • 如果 X1 X2 ... Xn 都能推 ε,则 ε ∈ FIRST(A)。
  4. 迭代:直到集合不再变。

例子

r 复制代码
S → E
E → T + E | T
T → id | ( E )
  • FIRST(T) = { id, ( }(id 和 ( 是开头)。
  • FIRST(E) = FIRST(T) = { id, ( }。
  • FIRST(S) = FIRST(E) = { id, ( }。

FOLLOW 集合:后面跟啥?

感性理解

FOLLOW 集合像是看一个符号的"后路"。编译器解析到某个部分(比如 T),得知道后面会接啥------是 "+"?";"?还是 ")"?FOLLOW 集合把这些"可能的后续"列出来,帮编译器规划下一步。

形式化表达

FOLLOW(A) 是非终结符 A 在推导中后面可能紧跟的终结符集合。如果 A 是开始符号,$ ∈ FOLLOW(A)。

构造方法

  1. 开始符号:FOLLOW(S) 加 $。
  2. 产生式 A → α B β
    • FIRST(β)(去掉 ε)加到 FOLLOW(B)。
    • 如果 β 能推 ε 或为空,把 FOLLOW(A) 加到 FOLLOW(B)。
  3. 迭代:直到集合不再变。

例子

r 复制代码
S → E ;
E → T + E | T
T → id | ( E )
  • FOLLOW(S) = { $ }(开始符号)。
  • FOLLOW(E) = { ;, ) }(S → E ; 得 ;,T → ( E ) 得 ))。
  • FOLLOW(T) = { +, ;, ) }(E → T + E 得 +,E → T 得 FOLLOW(E))。

为啥都只关心终结符?

FIRST 和 FOLLOW 是为预测式分析(比如 LL(1))服务的,编译器最终要处理的 token 是终结符("id"、"+" 之类),非终结符只是推导的"工具",所以它们都只收集终结符。

小结

有了开头的表格,你应该能一眼看出 FIRST 和 FOLLOW 的区别了吧!FIRST 管开头,FOLLOW 管后续,都是终结符的"侦察员"。试着拿个小文法算算它们的集合,动手练练就更明白了。加油哦!

相关推荐
覆东流4 小时前
7.Java数组
java·开发语言·后端
threerocks4 小时前
AI 原生软件开发生命周期手册 - 如何借助 AI,逐阶段改造软件开发生命周期
前端·javascript·后端
JavaPub-rodert4 小时前
王仕宇在 Go Context 如何解决协程泄漏与超时控制
开发语言·后端·golang·iphone·javapub·王仕宇
深漂的华哥5 小时前
Ruoyi-Plus前后端分离场景下,数据加密传输
java·spring boot·后端·开源·maven·ruoyi
why技术6 小时前
eli5,我觉得这个全网在吹的技能,使用体验真的很一般啊。
前端·人工智能·后端
学习星球6 小时前
Qwik 框架入门实战:从开源项目 Qwik City 开始,用可恢复性替代水合
后端·前端框架·开源·c5全栈
IT_陈寒8 小时前
被Java的final坑惨了,这些细节你可能也忽略了
前端·人工智能·后端
Zadig8 小时前
企业 Agent 总烂在 Demo 里?Zadig 工作流 AI 任务给了一条路
后端·devops
Zadig9 小时前
告别"人肉扛雷":Zadig 用 AI 接管发布前最脏最累的 15 分钟
后端·aiops
Nturmoils9 小时前
向量数据库不该成为新孤岛:KingbaseES 多模融合架构如何减少数据搬运
后端