对编译原理中First、Follow、Select集的一些不算太抽象的理解

2024-03-01 16:50

本文主要是介绍对编译原理中First、Follow、Select集的一些不算太抽象的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

对编译原理中First、Follow、Select集的一些不算太抽象的理解

刚开始接触的时候非常懵,不知道是在算什么,在干什么,去询问大佬和老师是否有更生动的理解方式,但是他们都达成一致说反向理解(然而我还是没听懂)

趁着写课后作业的机会再翻了翻书本,看了书上例题,进行了预习回顾,研究了一些个人认为不算太差的适合普通人类大学牲理解的角度,在此记录

下面以一道例题作为例子,核心是通过一个树状推导结构来理解!

example1
有一说一,可以不看上面这图,直接看下面的推导图即可,重在理解!

我们之前学过推导归约,我们这里先用推导,画出一个推导的树状结构

  1. 以S的First为例:

example2

图中红色的非终结符就是S的First集,即{ε,a,b}

来想一想First集含义:First(S)是指S能经过多步得到的左边第一个终结符

当然,既然是终结符,你就会想,有个特殊的终结符ε,需要对他特殊处理吗?

答:暂时放在这里,First集是可以包含ε的,就如上面S的First集里面有空一样,目前先保留着

  1. 下面以另一题的Follow(A)分析为例:

example3
你可以先去书本上看着规则啃一啃,然后会发现,Follow都是看产生式的右边该字母后面跟的是啥终结符,这一点理解很关键,意思就是:如果在上面这颗树中找Follow(A),那么按照规则,就是找到了A后面的B(这符合Follow的含义),然后取First,即First(B).

当然,你可能会想,要是A的是最后一个符号呢?它后面没有上图一样的B,该怎么办?

答:按照书上,继续对产生式左侧求Follow,也即求Follow(S)

总的来说:

  • First(A)就是取A能产生的、第一位是终结符的集合
  • Follow(A)就是取产生式右边紧跟在A后面的那个符号的First集

接下来是重量级Select集合

可以这么说,前面的First和Follow集都是为Select集做铺垫的,他们只是工具,目的只是为了求Select集,因此前面求得基本上不会全用上!!!

Select集含义:找出产生式能推导出的非终结符
我觉得像是对一条产生式能力的评估,找出一条产生式能够有多大的"潜力"(能推导出哪些终结符),这就是所谓“Select集”正在Select的东西

那么我们来想一想,Select集怎么依据前面的First和Follow集得到呢?
或者说,一条产生式的“潜力”怎么通过First和Follow集得到?

回顾一下前面的总结:

First(A)就是取A能产生的、第一位是终结符的集合

Follow(A)就是取产生式右边紧跟在A后面的那个符号的First集

例如有产生式A=>α,那么它的“潜力”有多大?

  1. 我们肯定会想:如果说,α可以在不断地左推能推导到一个第一个符号为终结符的串,那就可以说这个产生式具有这样的“潜力”
  2. 但是,如果α走了什么歪门邪道,在命运的交叉路口选错了方向,最后得到了一整个空串,那么该怎么鉴定它的“潜能”呢?这时,说明A选择α是一个错误的选择,A会寻找自己的Follow,因为根据这条产生式走下去是死路一条
  3. 不管怎么样,Select核心就是找这条产生式能产生的第一个终结符,可以理解为,都是找一个First,但是First找到空的话,就用到Follow,寻找空之后的第一个终结符(当然要是空的话继续找)Follow本质也是找第一个非空的终结符,只是前面的符号推出的都是空串,这个使命就落到了后面的符号身上(即Follow)

​ 于是,这时我才发现大佬和老师为什么说逆向理解了orz,其实归根到底都是为了研究一条产生式能变出什么花来,我们要的是产生式能推出的第一位是终结符的集合,来衡量一条产生式的“潜力”,然后编译器其实就是根据这种“潜力”来选择合适的产生式,进行推导化简的。
​ 其实是先有这个需求,然后生出了“如何合理选择合适产生式”的问题,于是有了Select集,目的是取产生式能推出来的第一位终结符,在之后就有了First集,但是若在First集中遇到空,说明第一个符号“白干了”,一点“潜力”都没有,于是要用到Follow集,也就是相应的“第一个符号不行,就找第二个”,由于第一个符号推出空,那么“整个产生式能推出的第一个终结符”就会由之后的符号的First确定!也就是相应的“第一个符号不行,就找第二个”,由于第一个符号推出空,那么“整个产生式能推出的第一个终结符”就会由之后的符号的First确定!

相信认真读完的你,结合书上的例题,写一写,相信会有不少的收获和更好的理解~

这篇关于对编译原理中First、Follow、Select集的一些不算太抽象的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/763138

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu

hdu4059容斥原理

求1-n中与n互质的数的4次方之和 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWrit

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

如何通俗理解注意力机制?

1、注意力机制(Attention Mechanism)是机器学习和深度学习中一种模拟人类注意力的方法,用于提高模型在处理大量信息时的效率和效果。通俗地理解,它就像是在一堆信息中找到最重要的部分,把注意力集中在这些关键点上,从而更好地完成任务。以下是几个简单的比喻来帮助理解注意力机制: 2、寻找重点:想象一下,你在阅读一篇文章的时候,有些段落特别重要,你会特别注意这些段落,反复阅读,而对其他部分