编译原理基础:FOLLOW 集合与 LL(1) 文法条件

编译原理基础:FOLLOW 集合与 LL(1) 文法条件

嗨!学编译原理是不是觉得脑子有点绕?上次我们聊了 FIRST 集合和提取公共左因子,今天我们来认识两个新朋友:FOLLOW 集合和 LL(1) 文法条件。别怕,我会用简单的话讲明白它们是什么,以及它们在编译器里怎么帮忙。

FOLLOW 集合:后面跟啥?

感性理解

想象你在读代码,编译器已经认出了一个符号(比如变量名),接下来它得猜猜后面会跟什么------是加号?分号?还是别的啥?FOLLOW 集合就像是编译器的"后视镜",告诉它某个符号后面可能会出现的东西。有了这个,编译器就不会在解析时迷路。

形式化表达

在文法里,FOLLOW 集合是针对某个非终结符(non-terminal),计算出它在推导过程中后面可能紧跟着的终结符(terminal)的集合。

定义一下:

  • 对于非终结符 A,FOLLOW(A) 是所有在推导中可能出现在 A 后面的终结符的集合。
  • 如果 A 是句子的结尾(比如整个程序的末尾),那 FOLLOW(A) 里还会包括特殊符号 $(表示输入结束)。

举个例子:

假设有文法:

bash 复制代码
S → E ;  
E → id | ( E )  
  • FOLLOW(E) 是啥?E 出现在 S → E ; 里,后面跟着 ";",还出现在 ( E ) 里,后面跟着 ")",所以 FOLLOW(E) = { ;, ) }。
  • FOLLOW(S) 呢?S 是开始符号,后面啥也没有,所以 FOLLOW(S) = { $ }。

FOLLOW 集合的作用是啥?它帮编译器在解析时知道"接下来该期待啥",尤其在预测式分析里特别有用。

LL(1) 文法条件:让解析不纠结

感性理解

你有没有遇到过那种选择题,两个选项开头长得一模一样,搞得你完全不知道选哪个?编译器也讨厌这种"纠结"的情况。LL(1) 文法就像是给编译器定了个规矩:每次看一个符号,就能立刻决定走哪条路,不用犹豫。简单说,它让解析变得"干脆利落"。

形式化表达

LL(1) 文法是一种上下文无关文法,满足以下条件:

  • L:从左到右扫描输入。
  • L:从左推导(leftmost derivation)。
  • 1:只看一个符号(lookahead 一个 token)就能决定用哪个产生式。

具体条件是:对于一个非终结符 A 的所有产生式 A → α | β:

  1. FIRST(α) 和 FIRST(β) 不能有交集(开头不能撞车)。
  2. 如果 α 或 β 能推导出空串 ε,那么 FIRST(β) 或 FIRST(α) 不能和 FOLLOW(A) 有交集(空串的情况不能和后面冲突)。

举个例子:

文法:

css 复制代码
S → a S | b  
  • FIRST(a S) = { a },FIRST(b) = { b },没交集,满足条件。
    但如果改成:
css 复制代码
S → a S | a T  
  • FIRST(a S) = { a },FIRST(a T) = { a },有交集,就不是 LL(1) 的了。

这俩咋配合?

  • FOLLOW 集合:帮 LL(1) 分析器判断某个非终结符推导完后,后面会跟啥,尤其在处理空串时特别关键。
  • LL(1) 条件:用 FIRST 和 FOLLOW 集合来检查文法是不是"干脆"的,能不能一步到位解析。

比如预测分析表(parsing table)就是靠 FIRST 和 FOLLOW 集合填出来的。编译器看到输入符号,查表就能知道用哪个产生式,效率超高!

小结

FOLLOW 集合像是编译器的"后视镜",告诉它后面可能跟啥;LL(1) 文法条件则是"交通规则",保证解析时不撞车、不纠结。理解了这两个,你就掌握了预测式分析的核心啦!下次可以试着自己写个小文法,算算 FIRST 和 FOLLOW,看看能不能满足 LL(1),动手玩玩就更明白了。加油哦!

相关推荐
Asthenia041210 分钟前
为什么把私钥写在代码里是一个致命错误
后端
程序员一诺16 分钟前
【Flask开发】嘿马文学web完整flask项目第2篇:2.用户认证,Json Web Token(JWT)【附代码文档】
后端·python·flask·框架
Asthenia041219 分钟前
如何在 Java 中正确判空 BigDecimal 等数据类型
后端
冷琅辞32 分钟前
Swift语言的跨平台开发
开发语言·后端·golang
Asthenia04121 小时前
Pandas期末备考:常见问题解析
后端
今夜有雨.1 小时前
使用C++实现HTTP服务
开发语言·网络·c++·后端·网络协议·tcp/ip·http
东方苾梦1 小时前
Lua语言的安全开发
开发语言·后端·golang
Asthenia04121 小时前
Spring Boot @Conditional 注解分析与实际业务场景应用
后端
慕离桑1 小时前
HTML语言的数据可视化
开发语言·后端·golang
我命由我123451 小时前
C++ - 头文件基础(常用标准库头文件、自定义头文件、头文件引入方式、防止头文件重复包含机制)
服务器·c语言·开发语言·c++·后端·visualstudio·visual studio code