惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Hacker News
The Hacker News
GbyAI
GbyAI
雷峰网
雷峰网
罗磊的独立博客
WordPress大学
WordPress大学
博客园_首页
Hugging Face - Blog
Hugging Face - Blog
The Cloudflare Blog
云风的 BLOG
云风的 BLOG
F
Full Disclosure
Google DeepMind News
Google DeepMind News
C
Cyber Attacks, Cyber Crime and Cyber Security
NISL@THU
NISL@THU
S
Schneier on Security
T
Tor Project blog
C
Cybersecurity and Infrastructure Security Agency CISA
Recent Announcements
Recent Announcements
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Check Point Blog
P
Palo Alto Networks Blog
C
CERT Recently Published Vulnerability Notes
S
Secure Thoughts
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Last Week in AI
Last Week in AI
T
Threatpost
I
Intezer
Y
Y Combinator Blog
G
GRAHAM CLULEY
MyScale Blog
MyScale Blog
阮一峰的网络日志
阮一峰的网络日志
T
The Exploit Database - CXSecurity.com
Scott Helme
Scott Helme
A
Arctic Wolf
Martin Fowler
Martin Fowler
Hacker News: Ask HN
Hacker News: Ask HN
V
V2EX
B
Blog RSS Feed
The Last Watchdog
The Last Watchdog
博客园 - 司徒正美
Simon Willison's Weblog
Simon Willison's Weblog
V
Vulnerabilities – Threatpost
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
www.infosecurity-magazine.com
www.infosecurity-magazine.com
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
AI
AI
C
Cisco Blogs
T
The Blog of Author Tim Ferriss

风萧古道 - 勤学苦练,年复一年

游戏服务器开发经验(五)应对复杂需求 沉浸式体验东汉末年生活 - 《真三国无双 起源》玩后感 怒其不争!致2025年HLTV的Top18-NiKo Linux家用服务器维护指南 游戏服务器开发经验(四)避免写Bug的习惯、技巧和心态 游戏服务器开发经验(三)线上维护 游戏服务器开发经验(二)避免内存泄露 游戏服务器开发经验(一)道具防刷 35岁找不到工作,绝对不会是软件开发人员的结局 用爱发电项目开发两个月的心得体会 以魏延“子午谷奇谋”讨论软件需求可行性问题 MQTT协议中可变长度的具体计算方式(有计算过程解析) 关于游戏服务器配置表功能的探讨 Java并发编程中上锁的几种方式 如何用C++分割一个字符串? CSAPP第二章-信息的表示与处理 我的自我介绍 Windows XP虚拟机中文版无需激活下载 Java TreeSet的一些用法和特性 Linux C++ Socket实战 传统软件服务器与游戏服务器架构区别 独立个人项目开发心得 - 任务切分、挑战性、实用性和半途而废 使用Python实现简单UDP Ping 使用Python开发一个简单的web服务器 Kotlin手动实现一个最简单的哈希表 Kotlin实现二叉堆、大顶堆、优先级队列 搭建Spark实战环境(3台linux虚拟机集群)(一)样板机的搭建 Springboot操作MongoDB,包括增改查及复杂操作 Unison在Linux下的安装与使用 Java实现类似WINSCP访问远程Linux服务器,执行命令、上传文件、下载文件 一个被废弃的项目——自动爬取信息然后发给我自己邮箱上 Python连接MongoDB和Oracle实战 MongoDB常用查询语句 vue和springboot项目部署到Linux服务器 Python的一些用法(可能不定时更新) java正则表达式 - 双反斜杠(\)和Pattern的matches()与find() 简述爬虫对两种网站的不同爬取方式 Vue的路由配置及手动改地址栏为啥又跳转回来?? [JavaScript]JS基础知识 [Mybatis]逆向工程中Select语句查询不出‘TEXT’字段 [Spring]Spring学习笔记 [算法]分布估计算法 - 一种求解多维背包问题的混合分布估计算法_王凌 [日常]我做独立博客的原因 人间值得 深入理解计算机系统 想想就开心! 最重要的事,只有一件 藏书 被讨厌的勇气 关于 简历 朋友 尊重自己:给予与接收的心灵艺术
[编译原理]FIRST、FOLLOW和SELECT
JonathanLin · 2018-04-30 · via 风萧古道 - 勤学苦练,年复一年

FIRST(α)为α的开始符号集或者首符号集。

定义

设G=(VT,VN,S,P)是上下文无关文法 ,FIRST(α)={a|α能推导出aβ,a∈VT,α,β∈V*} 。

特别的,若α能推导出ε,则规定ε∈FIRST(α).

VT为终结符集,VN为非终结符集,S称作识别符或开始符,P为规则(α→β)的集合。

根据定义求解FIRST集

(对每一文法符号X∈V 计算FIRST(X))

若X∈VT,则FIRST(X)={X}; 若X∈VN,且有产生式X→a…,则把a加入到FIRST(X)中; 若X∈VN,X→ε也是一条产生式,则把ε也加到FIRST(X)中; 若X→Y…是一个产生式且Y∈VN,则把FIRST(Y)中的所有非ε元素都加到FIRST(X)中; 若X→Y1 Y2 … Yk是一个产生式,Y1,Y2,…Y(i-1)都∈VN(1≤i≤K),而且,对于任何j(1≤j≤i-1),FIRST(Yj)都含有ε (即Y1…Y(i-1)=>*ε),则把FIRST(Yj)中的所有非ε元素和FIRST(Yi)中的所有元素都加到FIRST(X)中; 特别是,若所有的FIRST(Yj,j=1,2,..,K)均含有ε,则把ε加到FIRST(X)中。

反复使用上述2~5步,直到每个符号的FIRST集合不再增大为止。

FOLLOW集

FOLLOW(A)为非终结符A的后跟符号集合。

定义

设G=(VT,VN,S,P)是上下文无关文法,A∈VN,S是开始符号, FOLLOW(A)={a|S能推导出μAβ,且a∈VT,a∈FIRST(β),μ∈VT* ,β∈V+},若S能推导出μAβ,且β能推导出ε, 则#∈FOLLOW(A)。 也可定义为:FOLLOW(A)={a|S能推导出…Aa…,a ∈VT} ,若有S能推导出…A,则规定#∈FOLLOW(A) ,这里我们用‘#’作为输入串的结束符。

计算FOLLOW集

任何FOLLOW(S)都包含输入终止符号#,其中S是开始符号 如果存在产生式,A->αBβ,则将FIRST(β)中除ε以外的符号都放入FOLLOW(B)中 如果存在产生式,A->αB,或A->αBβ,其中FIRST(β)中包含ε,则将FOLLOW(A)中的所有符号都放入FOLLOW(B)中.

SELECT集

SELECT集是选择符号集。

定义及计算过程

给定上下文无关文法的产生式A→α, A∈VN,α∈V*, 若α不能推导出ε,则SELECT(A→α)=FIRST(α) 如果α能推导出ε则:SELECT(A→α)=(FIRST(α) –{ε})∪FOLLOW(A) 需要注意的是,SELECT集是针对产生式而言的。

例题

《编译原理》第三版,p100页,第2题:

对下面的文法G: E→TE‘ E‘→+E|ε T→FT' T‘→T|ε F→PF' F’→*F’|ε P→(E)|a|b|^

问:

  1. 计算这个文法的每个非终结符的FIRST集和FOLLOW集。
  2. 证明这个文法是LL(1)的。
  3. 构造它的预测分析表。
  4. 构造它的递归下降分析程序。

答:

1.计算这个文法的每个非终结符的FIRST集和FOLLOW集。

FIRST(P) = {a,b,(,^} FIRST(F) = FIRST(P) = {a,b,(,^} FIRST(T) = FIRST(F) = {a,b,(,^} FIRST(E) = FIRST(T) = {a,b,(,^} FIRST(E’) = {+,ε} FIRST(T’) = FIRST(T) ∪ {ε} = {a,b,(,^,ε} FIRST(F’) = {*,ε}

FOLLOW(E) = {#,)} FOLLOW(E’) = FOLLOW(E) = {#,)} FOLLOW(T) = (FIRST(E’) - {ε}) ∪ FOLLOW(E) = {+,#,)} FOLLOW(T’) = FOLLOW(T) = {+,#,)} FOLLOW(F) = (FIRST(T’) - {ε}) ∪ FOLLOW(T) = {a,b,(,#,^,+,)} FOLLOW(F’) = FOLLOW(F) = {a,b,(,#,^,+,)} FOLLOW(P) = (FIRST(F’) - {ε}) ∪ FOLLOW(F) = {*,a,b,(,#,^,+,)}

FIRSTFOLLOW
E{a,b,(,^}{#,)}
E'{+,ε}{#,)}
T{a,b,(,^}{+,#,)}
T'{a,b,(,^,ε}{+,#,)}
F{a,b,(,^}{a,b,(,#,^,+,)}
F'{*,ε}{a,b,(,#,^,+,)}
P{a,b,(,^}{*,a,b,(,#,^,+,)}

2.证明这个文法是LL(1)的。

考虑下列产生式: E‘→+E|ε T‘→T|ε F’→*F’|ε P→(E)|a|b|^

FIRST(+E) ∩ FIRST(ε) = {+} ∩ {ε} = ∅ FIRST(T) ∩ FIRST(ε) = {(,a,b,^} ∩ {ε} = ∅ FIRST(F’) ∩ FIRST(ε) = {} ∩ {ε} = ∅ FIRST((E)) ∩ FIRST(a) ∩ FIRST(b) ∩ FIRST(^) = ∅

FIRST(E’) ∩ FOLLOW(E’) = {+,ε} ∩ {#,)} = ∅ FIRST(T’) ∩ FOLLOW(T’) = {(,a,b,^,ε} ∩ {+,#,)} = ∅ FIRST(F’) ∩ FOLLOW(F’) = {*,ε} ∩ {(,A,B,^,+,),#} = ∅

所以,该文法是LL(1)文法。