如何求FIRST集、FOLLOW集、SELECT集---方法和例题讲解

注:α、β表示符号串

如何求FIRST集

(一)求符号的FISRST集

对于文法G中的任意一个符号X(X属于终结符号和非终结符号),其FISRST(x)的产生如下:
(1),若X属于终结(VT),则FIRST(X)={X}
(2),若X属于非终结符号(VN),且有形如X->a的产生式(a属于非终结符号)或者形如X->ε,
	  则将a或者ε加入FIRST(X)中
(3),如果文法中有如下的产生式
					X->Y1Y2....Yk
		① 若Y1属于非终结符号,则把FIRST(Y1)中的一切非ε符号加入FIRST(X)中
		②若Y1属于终结符号,则把Y1入到FIRST(X)中
		③ 若对于一切2≤i≤k,若Y1Y2....Yk均为非总结符号,
		  其中存在Yj(1≤j≤i-1),
		  使得ε∈FIRST(Yj),则将FIRST(Yj)中的一切非ε符号加入FIRST(X)中
		④若对于一切1≤i≤k,都有ε∈FIRST(Yi),则将ε加入到FIRST(X)中
		(注:③和④对于复杂情况的ε的加入做了探讨)

例:求文法G[E]:
在这里插入图片描述
中非终结符号的FIRST集
在这里插入图片描述

(二)求符号串的FIRST

对于文法G的任意符号串α=X1X2...Xn,则FIRST(α)的产生如下:
	(1)置FIRST(α)=Ø
	(2)将FIRST(X1)中的一切非ε符号加入到FIRST(α)中
	(3)若ε∈FISRT(X1),将FIRST(X2)中的一切非ε加入到FIRST(α)中
			若ε∈FISRT(X1)和ε∈FIRST(X2),将FIRST(X3)中的一切非ε加入到FIRST(α)中
			依次类推
	(4)若对于一切1≤t≤n,ε∈FIRST(X),则将ε加入FIRST(X)中

例:参考上述题目,求
在这里插入图片描述
的FIRST集
在这里插入图片描述

如何求FOLLOW集

(1)对于文法开始符号S,令#∈FOLLOW(S)
(2)(重点)看产生式右部:
	①若产生式形如A->αBβ的产生式,且β≠ε,则将FIRST(β)中的一起非ε加入到FOLLOW(B)中
	②若产生式形如A->αB或者A->αBβ(ε∈FIRST(β))的产生式,
	 则将FOLLOW(A)中的全部元素加入到FOLLOW(B)中
(3)FOLLOW集中无ε

例如:求文法G[E]:
在这里插入图片描述
中非终结符号的的FOLLOW集
在这里插入图片描述

如何求SELECT集

对于产生式P->α的可选集(SELECT)产生如下
1 若α不能推出ε,则
	SELECT(P->α)=FIRST(α)
2,若α能推出ε,则
	SELECT(P->α)=(FIRST(α)-{ε})∪FOLLOW(P)

例:求文法G[S]:
在这里插入图片描述
所有产生式的SELECT

在这里插入图片描述

<think>好的,用户需要详细解释递归下降分析文法、LL(1)、算符优先文法LR文法(包括LR(0)、SLR(1)、LR(1))之间的区别,并整理相关习题帮助备考编译原理期末考试。首先,用户之前已经询问过语法制导翻译、符号表等概念,现在转向语法分析的不同方法,可能是在复习过程中遇到了混淆点。 首先,用户是零基础,所以需要从基本概念入手,逐步展开,避免使用过于专业的术语,或者使用时必须解释清楚。用户可能对自顶向下自底向上的分析方法不太清楚,所以需要先明确分类,再逐一解释每种方法的特点、优缺点以及区别。 接下来,需要明确各个文法的核心特点它们之间的区别。例如,递归下降属于自顶向下的分析,而LL(1)是其中的一种,需要预测分析表。算符优先属于自底向上,但不同于LR,它主要处理表达式,而LR更通用。LR的不同变体(LR(0)、SLR、LR(1))的区别在于项目展望符的处理,需要详细说明它们的构造冲突解决方式。 用户提到分不清这些文法,可能需要对比表格来清晰展示差异。同时,用户请习题巩固,所以需要整理典型例题,涵盖判断文法类型、构造分析表、分析冲突等,帮助用户通过练习加深理解。 在组织回答时,结构要清晰,分点解释每个文法,再对比区别,最后给出习题。需要确保语言通俗易懂,例子具体,比如用简单的文法示例说明分析过程。同时,注意用户可能在考试中会遇到选择题、判断题构造题,所以习题应覆盖这些类型。 最后,需要检查是否覆盖了用户提到的所有文法类型,确保没有遗漏,并且解释准确。可能需要回顾编译原理教材中的关键点,确保内容正确,比如LR(0)SLR的区别在于是否使用Follow,而LR(1)使用向前看符号,避免冲突。</think>好的!这些语法分析方法是编译原理中的核心内容,但容易混淆。我会从**基础概念、特点、区别**入手,帮你理清思路,并附上**典型习题**供练习巩固。以下内容分点整理,方便记忆: --- ## 一、**总体分类与核心区别** ### 1. **两大分析方向** - **自顶向下(Top-Down)**:从起始符号开始,逐步推导出输入串。 - **代表方法**:递归下降分析、LL(1)文法。 - **自底向上(Bottom-Up)**:从输入串开始,逐步归约到起始符号。 - **代表方法**:算符优先文法、LR文法(LR(0)/SLR(1)/LR(1))。 ### 2. **核心区别表** | 方法 | 分析方向 | 核心机制 | 适用范围 | 冲突处理能力 | |---------------|------------|------------------------|-------------------|--------------| | 递归下降 | 自顶向下 | 递归函数模拟产生式 | LL(1)文法 | 弱 | | LL(1) | 自顶向下 | 预测分析表(First/Follow) | LL(1)文法 | 弱 | | 算符优先 | 自底向上 | 算符优先级比较 | 表达式类文法 | 中 | | LR(0) | 自底向上 | 项目规范族(无展望符)| 无冲突的LR(0)文法 | 弱 | | SLR(1) | 自底向上 | LR(0)+Follow解决冲突 | 比LR(0)稍强 | 中 | | LR(1) | 自底向上 | 项目+展望符 | 最广泛的LR文法 | 强 | --- ## 二、**详细解释与对比** ### 1. **递归下降分析(Recursive Descent Parsing)** - **特点**: - 为每个非终结符编写一个递归函数。 - 根据当前输入符号选择产生式展开。 - 需要**无左递归**且**无回溯**(即LL(1)文法)。 - **例子**: ```plaintext 文法:E → T | T + E 函数 E() { T(); // 匹配T if (当前符号是+) { match(+); // 匹配+ E(); // 递归调用E } } ``` ### 2. **LL(1)文法** - **特点**: - **L**eft-to-right输入扫描,**L**eftmost推导,**1**个符号前瞻。 - 必须满足:对每个非终结符A的产生式A→α|β,有**First(α) ∩ First(β) = ∅**,且若α能推导出ε,则**First(β) ∩ Follow(A) = ∅**。 - 使用**预测分析表**(行是非终结符,列是终结符,单元格填产生式)。 - **关键公式**: - 计算`SELECT(A→α) = First(α) ∪ ( if α⇒*ε then Follow(A) else ∅ )` ### 3. **算符优先文法(Operator Precedence Grammar)** - **特点**: - 适用于**表达式分析**(如加减乘除)。 - 定义算符之间的优先级(如`*` > `+`)。 - **不关注非终结符**,只比较相邻算符的优先级。 - 没有明确的归约规则(可能归约错误,但效率高)。 - **核心关系**: - `a ⋖ b`:a的优先级低于b(移进) - `a ≐ b`:优先级相等(如括号匹配) - `a ⋗ b`:a的优先级高于b(归约) ### 4. **LR文法家族** #### **(1) LR(0)** - **特点**: - 项目规范族不包含**展望符**(只看当前状态)。 - 构造分析表时可能产生**移进-归约冲突**或**归约-归约冲突**。 - 仅适用于无冲突的LR(0)文法(极少)。 - **项目形式**:`A → α·β`(点号表示分析进度)。 #### **(2) SLR(1)(Simple LR)** - **改进**: - 在LR(0)基础上,用**Follow**解决冲突。 - 冲突判断:若Follow(A)当前输入符号的交为空,则允许归约。 - **局限性**:Follow可能过大,无法解决所有冲突。 #### **(3) LR(1)** - **核心改进**: - 每个项目携带**展望符**(即归约时需要满足的后续符号)。 - 项目形式:`[A→α·β, a]`(a是展望符)。 - 更精确的冲突解决能力,适用范围最广。 - **代价**:项目数量大幅增加,构造复杂。 --- ## 三、**典型习题与解析** ### 习题1:判断文法类型 **题目**: 判断以下文法属于LL(1)、LR(0)、SLR(1)中的哪一类? ``` S → aAB | bBA A → ε | c B → d | ε ``` **解析步骤**: 1. **计算First/Follow**: - First(S) = {a, b} - First(A) = {c, ε} - First(B) = {d, ε} - Follow(A) = {d, $}(因为A后面是B,B可能为ε) - Follow(B) = {$} 2. **检查LL(1)条件**: - S的两个产生式`aAB``bBA`的First无交,满足LL(1)。 - A的两个产生式`ε``c`:First(c)={c},First(ε)={ε},且First(c) ∩ Follow(A) = {c} ∩ {d, $} = ∅ → 满足LL(1)。 - B同理:First(d)={d}, First(ε)={ε},且First(d) ∩ Follow(B) = ∅ → 满足LL(1)。 → **该文法是LL(1)文法**。 --- ### 习题2:构造LR(0)项目规范族 **题目**: 为以下文法构造LR(0)项目规范族: ``` S → A A → aB | b B → c ``` **解析步骤**: 1. **扩展文法**(添加增广产生式): ``` S' → S S → A A → aB | b B → c ``` 2. **构造初始项目I₀**: - `[S'→·S]` - 闭包操作:加入`[S→·A]`,再展开到`[A→·aB]``[A→·b]`。 3. **转移与后续项目**: - 从I₀读`S`进入I₁:`[S'→S·]`(接受状态)。 - 从I₀读`A`进入I₂:`[S→A·]`。 - 从I₀读`a`进入I₃:`[A→a·B]`,闭包加入`[B→·c]`。 - 从I₃读`B`进入I₄:`[A→aB·]`。 - 其他转移类似... --- ### 习题3:SLR(1)冲突解决 **题目**: 给定LR(0)项目: ``` I₁: [A→α·, a] [B→β·γ, b] ``` 若Follow(A) = {a, c},当前输入符号为a,是否冲突? **解析**: - **归约-归约冲突**:如果存在多个归约项目。 - **移进-归约冲突**:如果某项目既可移进又可归约。 - 本例中:若输入符号是a,且Follow(A)包含a,则允许按A→α归约;同时若有移进项目,则冲突需用Follow判断。 --- ## 四、**总结与记忆技巧** 1. **自顶向下 vs 自底向上**: - 递归下降LL(1)需要预测产生式,适合简单文法。 - LR家族更强大,能处理复杂文法,但实现复杂。 2. **LR家族区分**: - **LR(0)**:无展望符,冲突多。 - **SLR(1)**:用Follow解决部分冲突。 - **LR(1)**:携带展望符,最精确。 3. **考试重点**: - 计算First/Follow(LL(1)SLR需要)。 - 构造LR(0)/SLR项目规范族。 - 判断冲突类型并解决。 --- **考前建议**:多练习构造分析表、计算First/Follow、画项目规范族,并对比不同方法的优缺点。如果有具体题目,可以随时问我! 💪
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值