编译原理:语法分析
目录
- 引言
- 上下文无关文法 CFG: Context-Free Grammar
- 定义
- 推导方法
- 最左推导和最右推导
- 分析树
- 分析树->抽象语法树
- 常见的上下文无关文法
- 文法设计
- 二义性文法
- 扩展巴科斯范式:EBNF extended Backus Normal Form
- 文法和语言分类
- 相关术语
- 直接推导
- +推导
- *推导
- 句型、句子、语言
- 短语、简单短语、句柄
- 正则文法
- DFA->正则文法
- 正则文法->DFA
- DFA->正则表达式
- 正则文法->正则表达式
- 正则表达式->正则文法
- 自顶向下分析方法(LL分析算法) top-down parsing
- 回溯分析方法backtracking parser
- 预测分析方法 predictive paeser
- 递归下降分析 recursive-descent parsing
- LL(1)分析法 ll(1) parsing (重点)
- First集合,Follow集合 (重点)
- 自底向上分析方法(LR分析算法)bottom-up parsing
引言
语法分析器的作用:token序列->分析树、抽象语法树
语法错误可能有:
- 关键字、标识符拼写错误,如intege
- 语法结构出错,少分号,begin/end不匹配
- 静态语义错误:类型不一致、参数不匹配,如需要传入double却传入了char
- 动态语义错误:无穷递归(这就是为什么有的编译器会报错whille(t){}里没有t–,即使你在块里写了它也找不到,因为它只看一开始有没有,很傻)、0作除数
处理目标:
- 正确报告错误以及地点(有一些明明是x行错误,却报y行错误)
- 迅速恢复(要么一直找,直到找到想要的记号,这样比较愚蠢;要么替换纠正,容易改不对,引发更多报错)
- 不影响源程序的分析速度
词法分析可以合并到文法当中
上下文无关文法 CFG: Context-Free Grammar
文法是对语言结构的定义和描述。即从形式上用于表述和规定语言的结构称为“文法”。如:“草吃羊”在文法上正确,但语义不正确。
定义
G=(T,N,P,S)
T 是终极符号集合,可以理解为token,一般用小写、黑体表示
N是非终结符号集合,一般用大写、小写斜体表示
P是产生式或文法规则A->a集合,其中A是非终结符,a是(TUN)*,如<句子>-><主语><宾语>
S是唯一的开始符号,是非终结符
另外,小写希腊字符表示文法符号串(可为空)
暂时没有自动生成上下文无关文法的工具,必须手动写
推导方法
给定文法G,从G的开始符号S开始推导,不断用相应规则的右部来替代规则的左部,每次仅用一条规则去推导,直到所有的非终结符都被终结符号替代为止。
依据上述过程,最终的串称为句子,所有句子的集合称为语言。定义如下: L ( G ) = { s ∣ S = > ∗ s } L(G)=\{s|S=>*s\} L(G)={s∣S=>∗s},其中,推出符号*表示经过0或多步推导出。
最左推导和最右推导
有若干语法成分同时存在时,总是从最左的语法成分进行推导,这称之为最左推导。(同理可以定义最右推导)
例:
文法:
exp->exp op exp|(exp)|**number**
op->+|-|\*
需要分析的字符串:(34-3)*42
推导过程:
exp=>exp op exp
=>exp op number
=>exp * number
=> (exp)*number
=>(exp op exp)*number
=>(exp op number)*number
=>(exp - number) * number
=>(number - number ) * number
上例是最右推导,最左推导如下:
(1) exp => exp op exp [exp -> exp op exp]
(2) => (exp) op exp [exp -> (exp)]
(3) => (exp op exp) op exp [exp -> exp op exp]
(4) => (number op exp) op exp [exp -> number]
(5) => (number - exp) op exp [ op -> - ]
(6) => (number - number) op exp [exp -> number]
(7) => (number - number) * exp [ op -> *]
(8) => (number - number) * number [exp -> number]
上下文无关文法举例:
- 文法G:E->(E)|a, 文法定义的语言是:L(G)={a,(a),((a)),…}={ ( n a ) n ∣ (^na)^n| (na)n∣n是>=0的整数}
- G:E->E+a|a,文法定义的语言是:L(G)={a,a+a,a+a+a,…}
- 正则式:a+,文法是G:A->Aa|a或者A->aA|a,语言是L(G)={ a n a^n an,n是>=1的整数}
- 正则式:a*,文法是G:A->Aa|ε或者A->aA|ε,语言是L(G)={ a n a^n an,n是>=0的整数}
- 文法G:E->(E) ,语言是L(G)={},没有终结符,没有句子,无限递归
分析树
以上例为例,
看序号可知是最左推导,与前序编号对应
下面是最右推导,与后序遍历对应
①父节点和子结点之间构成了一条文法规则
②叶节点都是终结符号,内部结点都是非终结符号
每个分析树只有唯一的一个最左推导和一个最右推导
分析树->抽象语法树
分析树复杂,但信息丰富,而抽象语法树简洁、抽象,用于语义分析
常见的上下文无关文法
- 算数表达式
exp->exp op exp|(exp)|**number**
op->+|-|\*
- if-else
下面这个文法,有重叠的部分,比较低效
G: statement -> if-stmt | other
if-stmt -> if ( exp ) statement |if ( exp ) statement else statement
exp -> 0 | 1
下面这个文法是有歧义的文法
G: statement -> if-stmt | other
if-stmt -> if ( exp ) statement else-part
else-part -> else statement | ε
exp -> 0 | 1
- 括号匹配文法
G: A ->(A)A|ε
- 带分号的文法
这个文法是错的,他的缺点是最后一个语句没有结束的分号
stmt-sequence -> stmt ; stmt-sequence | stmt
stmt -> s
下面这个文法可以,但是会推导出空语句:L(G’)= {ε, s;, s;s;, s;s;s;,…}
stmt-sequence -> stmt ; stmt-sequence | stmt | ε
stmt -> s
下面这个也是
stmt-sequence -> stmt-other1 stmt-other2
stmt-other1 -> stmt | ε
stmt-other2 -> ;stmt stmt-other2 | ;
stmt -> s
文法设计
二义性文法
可生成两个不同分析树的串的文法叫二义性文法。
如34-3*42
的分析树与语法树可以有两种。
算术表达式文法存在二义性的根源是什么?有2条规则都能往下推导,没有考虑优先级。
消除二义性的方法:
1.不修改文法,指定正确的分析树(只需手动修改生成的代码)LL分析表有冲突时选择其中一条
2.修改文法,会改得很乱
1.算术表达式修改文法,确定乘法优先级于加法;
exp -> exp addop exp | term
addop -> + | -
term -> term mulop term| factor
mulop -> *
factor -> (exp) | number
在此基础上,确定乘法和加法都是左结合的
exp -> exp addop term | term
addop -> + | -
term -> term mulop factor | factor
mulop -> *
factor -> (exp) | number
下面这个文法的缺陷是,输入者必须输入带括号的表达式
exp factor op factor | factor
factor (exp) | number
op + | – | *
2.if-else,悬挂的else问题在这里插入代码片
最近嵌套规则用于解决悬挂else问题
statement matched-stmt | unmatched-stmt
matched-stmt if ( exp ) matched-stmt else matched-stmt | other
unmatched-stmt if ( exp ) statement | if ( exp ) matched-stmt else unmatched-stmt
exp 0 | 1
下面的文法是强制if加上end
if-stmt -> if condition then statement-sequence end if |if condition then statement-sequence else statement-sequence end if
3.无关紧要的二义性文法:分号结尾的语句
stmt-sequence -> stmt-sequence ; stmt-sequence | stmt
stmt -> s
扩展巴科斯范式:EBNF extended Backus Normal Form
{}表示重复
用[]表示可选,比如:
G: statement if-stmt | other
if-stmt if ( exp ) statement [ else statement ]
exp 0 | 1
文法和语言分类
0型、1型、2型、3型(乔姆斯基层次)
- | 产生式 | 左部范围 | 右部范围 | 左部 | 右部 | 备注 |
---|---|---|---|---|---|---|
0型 | u->v | (TUN)+ | (TUN)* | >=1 | >=0 | 可计算枚举语言,短语结构文法 |
1型 | xUy->xuy | (TUN)+ | (TUN)* | >=1 | >=0 | 上下文相关文法 |
2型 | U->v | N | (TUN)* | =1 | >=0 | 上下文无关文法 |
3型 | U->t,U->Wt | N | TUN | =1 | <=2 | 正则文法、线性文法 |
越往高级,限制越多,高级的语言符合低级
(左线性) P:U -> t 或 U -> Wt 其中 U、W∈N t∈T
(右线性) P:U -> t 或 U -> tW 其中 U、W∈N t∈T
这一分类的研究意义在于模型的可解释性,但是它的描述能力较弱
相关术语
直接推导
+推导
等于说是通过一步或多步推导出来的
*推导
通过0步或多步推导
句型、句子、语言
文法G = (T, N, P, S),S =>* a ,
如果a是(TUN)*,那么a是句型 (存在非终结符号。即分析树的剖面);
如果a是T*,那么a是句子(全部是终结符号,也就是叶子节点)(句子属于句型)
文法G产生的语言是L(G[S]) = {a | S =>* a ,a ∈ T* }
短语、简单短语、句柄
G = (T, N, P, S),w = xuy ∈ (TUN)* 为文法的句型
若:S => xUy ,且 U =>+ u,则u是句型w相对于U的短语(子树)
若:S => xUy, 且 U => u,则u是句型w相对于U 的简单短语;
U是非终结符,u是一步或多步的TUN,xy都是0步或多步的TUN
任一句型的最左简单短语称为该句型的句柄。
例子:
黄色是剖面(句型)
可以发现,这种话的说法就是“u是句型xx相对于U的短语”,其中句型是固定的,因为这是题里给的,u是黄色的结点,U是他们规约以后蓝色的结点
简单短语也就是一步可以得出的,最左的简单短语是句柄
正则文法
DFA->正则文法
例子:
普通的转移直接把吃进的字符和到达的状态连起来当右部,出发点当左部;可接收的状态再加一条可以推出epsilon
正则文法->DFA
先按反过程画出来DFA,画完所有的以后加一个终态Z,把那些可以推出epsilon的状态都指向Z,把那些直接推出终结符的语句,也指向Z
DFA->正则表达式
将词法分析的流程反向做一遍
r = ( a ∣ b ) ∗ ( a a ∣ b b ) ( a ∣ b ) ∗ r = (a|b)*(aa|bb)(a|b)* r=(a∣b)∗(aa∣bb)(a∣b)∗
正则文法->正则表达式
递归即闭包
正则表达式->正则文法
上表反过来
自顶向下分析方法(LL分析算法) top-down parsing
从文法G的开始符号S开始推导得出句子t,遍历所有t,如果t==给定的句子s,那么s可以由G推导出来。
回溯分析方法backtracking parser
思想就是往下推导,如果不匹配就回溯,效率非常低,不聪明。没人用。
tokens[ ]; /* 词法分析得到的单词列表 */
int i = 0;
stack = [S]; /* 栈内放文法的开始符号 */
while ( stack != [] )if (stack[top] 是终结符号 t )if ( t == tokens[i] ) { i++; pop(); }else { backtrack( ) }else if (stack[top] 非终结符号 T )pop( ); push( 关于非终结符号T的下一条规则的右部 )
压栈的时候,是从右往左压,一旦栈顶是终结符就去匹配:不匹配就回溯,匹配就消掉
预测分析方法 predictive paeser
递归下降分析 recursive-descent parsing
LL(1)分析法 ll(1) parsing (重点)
First集合,Follow集合 (重点)
自底向上分析方法(LR分析算法)bottom-up parsing
相关文章:
编译原理:语法分析
目录 引言上下文无关文法 CFG: Context-Free Grammar定义推导方法最左推导和最右推导 分析树分析树->抽象语法树常见的上下文无关文法文法设计二义性文法扩展巴科斯范式:EBNF extended Backus Normal Form 文法和语言分类相关术语直接推导推导*推导句型、句子、语…...
React 中的 Lanes
React 中有一个 Lane 的概念,Lane 就像高速路上的不同车道,具有不同优先级,在 React Lane 通过一个 32 位的二进制数来表示。越小优先级别越高,SyncLane 级别最高。用二进制存储的方式,可以通过逻辑操作快速判断 Lane …...
【复旦邱锡鹏教授《神经网络与深度学习公开课》笔记】线性分类模型损失函数对比
本节均以二分类问题为例进行展开,统一定义类别标签 y ∈ { 1 , − 1 } y\in\{1,-1\} y∈{1,−1},则分类正确时 y f ( x ; w ) > 0 yf(x;w)>0 yf(x;w)>0,且值越大越正确;错误时 y f ( x ; w ) < 0 yf(x;w)<0 yf(x;…...
数组(C语言)(详细过程!!!)
目录 数组的概念 一维数组 sizeof计算数组元素个数 二维数组 C99中的变⻓数组 数组的概念 数组是⼀组相同类型元素的集合。 数组分为⼀维数组和多维数组,多维数组⼀般比较多见的是二维数组。 从这个概念中我们就可以发现2个有价值的信息:(1)数…...
视频生成模型 Dream Machine 开放试用;微软将停止 Copilot GPTs丨 RTE 开发者日报 Vol.224
开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…...
Vue30-自定义指令:对象式
一、需求:创建fbind指定 要用js代码实现自动获取焦点的功能! 二、实现 2-1、步骤一:绑定元素 2-2、步骤二:input元素获取焦点 此时,页面初始化的时候,input元素并没有获取焦点,点击按钮&…...
2024/06/13--代码随想录算法(贪心)3/6|134.加油站、135.分发糖果、860.柠檬水找零、406.根据身高重建队列
134.加油站 力扣链接 class Solution:def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:curSum 0 # 当前累计的剩余油量totalSum 0 # 总剩余油量start 0 # 起始位置for i in range(len(gas)):curSum gas[i] - cost[i]totalSum gas[i] - co…...
机器学习的分类
机器学习分类 机器学习是人工智能的一个分支,它使计算机系统能够从数据中学习并做出决策或预测。机器学习(Machine Learning)是一种基于数据驱动的方法,旨在通过自动化的统计模型和算法从数据中学习和提取模式,以进…...
【Linux】进程控制3——进程程序替换
一,前言 创建子进程的目的之一就是为了代劳父进程执行父进程的部分代码,也就是说本质上来说父子进程都是执行的同一个代码段的数据,在子进程修改数据的时候进行写时拷贝修改数据段的部分数据。 但是还有一个目的——将子进程在运行时指向一个…...
PFC旁路二极管、继电器驱动电路以及PFC主功率
R001和R002以及R003三个电阻作用是限放X电容上的电 整流桥串联两个BJ1和BJ2 电容C3:给整流桥储能,给后续llc供电 PFC工作是正弦波上叠加高频电流 PFC功率部分 2个PFC电感(选择两个磁芯骨架小,有利于散热)、2个续流二极管&…...
CrossOver 2024软件下载-CrossOver 2024详细安装教程
Crossover软件是一款可以在Mac、Linux和Chromebook上运行Windows程序的软件。 它是一款商业软件,由CodeWeavers公司开发,Crossover不是一个虚拟机或模拟器,它使用Wine技术来将Windows程序直接转换成可以在其他操作系统上运行的程序࿰…...
Spark MLlib机器学习
前言 随着大数据时代的到来,数据处理和分析的需求急剧增加,传统的数据处理工具已经难以满足海量数据的分析需求。Apache Spark作为一种快速、通用的集群计算系统,迅速成为了大数据处理的首选工具。而在Spark中,MLlib(…...
React Native将 ipad 端软件设置为横屏显示后关闭 Modal 弹窗报错
问题: 将 ipad 端软件设置为横屏显示后,关闭 Modal 弹窗报错。 Modal was presented with 0x2 orientations mask but the application only supports 0x18.Add more interface orientations to your apps Info.plist to fix this.NOTE: This will cras…...
JavaEE大作业之班级通讯录系统(前端HTML+后端JavaEE实现)PS:也可选网络留言板、图书借阅系统、寝室管理系统
背景: 题目要求: 题目一:班级通讯录【我们选这个】 实现一个B/S结构的电子通讯录,其中的每条记录至少包含学号、姓名、性别、班级、手机号、QQ号、微信号,需要实现如下功能: (1)…...
代码随想录算法训练营第37天|● 56.合并区间● 738.单调递增的数字
合并区间 56. 合并区间 - 力扣(LeetCode) 按照左边界从小到大排序之后,如果 intervals[i][0] < intervals[i - 1][1] 即intervals[i]的左边界 < intervals[i - 1]的右边界,则一定有重叠。(本题相邻区间也算重贴…...
SQL Server中的CTE和临时表优化
在SQL Server中,优化查询性能是数据库管理的核心任务之一。使用公用表表达式(CTE)和临时表是两种重要的技术手段。本文将深入探讨CTE如何简化代码,以及临时表如何优化查询性能。通过实例和详尽解释,我们将展示这两种技…...
CCRC信息安全服务资质认证是什么
什么是CCRC认证? CCRC 全称 China Cybersecurity Review Technology and Certification Center。CCRC认证是指中国网络安全审查技术与认证中心进行的信息安全服务资质认证。简称信息安全服务资质认证。 CCRC,即中国网络安全审查技术与认证中心࿰…...
第五十一天 | 1143.最长公共子序列
题目:1143.最长公共子序列718.最长重复子数组的区别是,子序列不要求连续,子数组要求连续。这一差异体现在dp数组含义和递推公式中,本题是子序列,那就要考虑上nums1[i - 1] ! nums2[j - 1]的情况。 本道题与 1.dp数组…...
未来的5-10年,哪些行业可能会被AI代替?
在未来的5-10年,多个行业可能会受到AI技术的影响,其中一些工作可能会被AI所代替。以下是对可能被AI替代的行业及工作的一些概述: 客户服务与代表:随着AI技术的发展,特别是自动话术对话和语音生成技术的进步࿰…...
据报道,FTC 和 DOJ 对微软、OpenAI 和 Nvidia 展开反垄断调查
据《纽约时报》报道,联邦贸易委员会 (FTC) 和司法部 (DOJ) 同意分担调查微软、OpenAI 和 Nvidia 潜在反垄断违规行为的职责。 美国司法部将牵头对英伟达进行调查,而联邦贸易委员会将调查 OpenAI 与其最大投资者微软之间的交易。 喜好儿网 今年 1 月&a…...
人工智能发展历程和工具搭建学习
目录 人工智能的三次浪潮 开发环境介绍 Anaconda Anaconda的下载和安装 下载说明 安装指导 模块介绍 使用Anaconda Navigator Home界面介绍 Environment界面介绍 使用Jupter Notebook 打开Jupter Notebook 配置默认目录 新建文件 两种输入模式 Conda 虚拟环境 添…...
Dijkstra算法的原理
Dijkstra算法的原理可以清晰地分为以下几个步骤和要点: 初始化: 引入一个辅助数组D,其中D[i]表示从起始点(源点)到顶点i的当前已知最短距离。如果起始点与顶点i之间没有直接连接,则D[i]被初始化为无穷大&a…...
maven引入依赖时莫名报错
一般跟依赖的版本无关,会报出 Cannot resolve xxx 的错误。 这种情况下去IDEA的setting中找maven的仓库位置 在仓库中顺着包路径下寻找,可能会找到.lastUpdated 的文件,这样的文件一般是下载失败了,而且在一段时间内不再下载&…...
graalvm编译springboot3 native应用
云原生时代容器先行,为了更好的拥抱云原生,spring boot3之后,推出了graalvm编译boot项目,利用jvm的AOT( Ahead Of Time )运行前编译技术,可以将javay源码直接构建成机器码二进制的文件ÿ…...
代码随想录Day58
392.判断子序列 题目:392. 判断子序列 - 力扣(LeetCode) 思路:定义重合数记录s与t的比对情况,挨个取出t的字符,与s的字符进行比较,如果相同,重合数就加1,跳到s的下一个字…...
Android Verified Boot (AVB) 与 dm-verity 之间的关系、相同点与差异点
标签: AVB; dm-verity ;Android Android Verified Boot (AVB) 与 dm-verity 之间的关系、相同点与差异点 概述 Android Verified Boot (AVB) 和 dm-verity 是 Android 操作系统中用于确保设备启动过程和运行时数据完整性的两个重要技术。尽管它们有着不同的实现和侧重点,…...
C++学习笔记“类和对象”:多态;
目录 4.7 多态 4.7.1 多态的基本概念 4.7.2 多态案例--计算器类 4.7.3 纯虚函数和抽象类 4.7.4 多态案例二 - 制作饮品 4.7.5 虚析构和纯虚析构 4.7.6 多态案例三-电脑组装 4.7 多态 4.7.1 多态的基本概念 多态是C面向对象三大特性之一 多态分为两类 静志多态: 函数…...
QT Udp广播实现设备发现
测试环境 本文选用pc1作为客户端,pc2,以及一台虚拟机作为服务端。 pc1,pc2(客户端): 虚拟机(服务端): 客户端 原理:客户端通过发送广播消息信息到ip:255.255.255.255(QHostAddress::Broadcast),局域网…...
PyTorch 统计属性-Tensor基本操作
最小 min, 最大 max, 均值 mean,累加 sum,累乘 prod … >>> a torch.arange(0,8).view(2,4).float() >>> a tensor([[0., 1., 2., 3.],[4., 5., 6., 7.]])>>> a.min() ## 最小值:tensor(0.) >>> a.ma…...
波拉西亚战记加速器 台服波拉西亚战记免费加速器
波拉西亚战记是一款新上线的MMORPG游戏,游戏内我们有多个角色职业可以选择,可以体验不同的战斗流派玩法,开放式的地图设计,玩家可以自由的进行探索冒险,寻找各种物资。各种随机事件可以触发,让玩家的冒险过…...
广东深圳宝安区疫情最新情况/网络优化工程师主要负责什么工作
ElasticSearch 2 (29) - 信息聚合系列之测试驱动 摘要 我们可以用以下几页定义不同的聚合和它们的语法,但学习聚合的最佳途径就是用实例来说明。一旦我们获得了聚合的思想,以及如何合理地嵌套使用它们,那么语法就变得不那么重要。 版本 elast…...
地图定位网站开发/本地网络seo公司
1.Smartbi Mining Smartbi Mining旨在为企业所做的决策提供预测性智能。通过深度数据建模,为企业提供预测能力支持文本分析、五大类算法和数据预处理,并为用户提供一站式的流程式建模、拖拽式操作和可视化配置体验。该平台不仅可为用户提供直观的流式建…...
南京做网站建设的公司/线下推广渠道和方式
首先对于n<100的点,直接暴力dp,f[i][j][k]表示时间为i,在i,j位置的方案数,枚举转移即可,期望得分40。 1 if(n<100)2 {3 if(t0)4 {5 f[0][100][100]1;6 …...
中山市建设局网站/如何进行网站性能优化?
我不是Facebook也不是Pinterest 粉丝,所以当朋友Orli发给我 Pinvolve的链接时,我很惊奇,它把 Facebook的动态更新以Pinterest式风格呈现出来,我很喜欢这个。在我眼里它提供了更好地方式来浏览世界上最大的社交网络,即使…...
网站案例/电商运营转行后悔了
目录 0. 相关文章链接 1. 原理 1.1. 为什么使用Flink On Yarn 1.2. Flink如何和Yarn进行交互 1.3. 两种方式 2. 操作 2.1. 关闭yarn的内存检查 2.2. 同步 2.3. 重启yarn 3. 测试 3.1. Session模式 3.2. Per-Job分离模式 0. 相关文章链接 Flink文章汇总 1. 原理 …...
win10做网站服务器/外贸推广平台
Laravel 嵌套事务 transactions 前言laravel 嵌套事务 transactions 实现调用示例:代码分析:总结:前言 关于 mysql 的事务嵌套可以查看这个地址: https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html 里面有这么一句话 Transactions cannot be nested. This i…...