当前位置: 首页 > news >正文

自己动手写编译器:语法解析的基本原理

在前面系列章节中我们完成了词法解析。词法解析的基本任务就是判断给定字符串是否符合特定规则,如果符合那么就给这个字符串分配一个标签(token)。词法解析完成后接下来的工作就要分配给语法解析,后者的任务就是判断一系列标签的组合是否符合特定规范。

语法解析遵守的规则叫巴克斯-诺尔范式,它由三部分组成,最左边的部分叫非终结符,然后跟着一个箭头,箭头右边是一系列终结符或者非终结符。它的意思是左边的概念可以分解成右边一系列概念的组合,举个具体例子:
人 -> 头 上半身 下半身
头 -> 头发 眼睛 耳朵 鼻子 嘴巴
上半身 -> 双手 胸部 肚子
下半身 -> 屁股 双腿

我们看上面的例子,在第一个表达式中左边是一个抽象概念“人”,箭头右边是人的组成部分或者说“人”可以分解成三个相对更具体一些的概念,也就是头,上半身,下半身。然后概念“头”又可以进一步分解成其他概念的组合,例如头发,眼睛等。这里需要注意的是,所有出现在箭头左边的概念都叫“非终结符”,所有只在箭头右边出现而且从来没有在箭头左边出现的概念叫“终结符”。非终结符可以进行分解,而终结符不能再继续往下分解。由上面一系列表达式形成的集合就叫”语法“,在语法解析中特别强调“上下文无关语法”,这个概念的意思是,语法规则只规定词法解析只分析标签的组合规律,至于这些标签的组合到底表达什么含义它不管。

例如 :
句子 -> 主语 谓语 宾语
上面的语法描述的是,一个中文句子可以分成三部分分别是主语,谓语和宾语,但上面的分解并不能告诉我们一个具体句子的内容是什么,也就是语法只关心句子的逻辑构造而不关心句子要传递的意义。这里还需要注意的是,箭头右边一系列概念的顺序很重要,顺序是语法规则的组成部分,例如合乎逻辑的“人头”必须满足鼻子在眼睛后面,如果这个顺序颠倒了,那么这个“头”就不是人头,而是异形的头。

语法解析的基本过程就是给定一个字符串,先对其进行词法解析得到一系列标签组合,然后根据给定语法表达式看看这些标签组合能否顺利分解,我们看一个具体例子,下面是针对数字和加号进行组合的加法算算数表达式语法:
STMT -> EXPR SEMI
EXPR -> FACTOR PLUS EXPR | FACTOR
FACTOR -> NUMBER

现在我们有一个字符串:“1+2;", 首先对这个字符串做词法解析得到 NUMBER PLUS NUMBER SEMI,现在我们需要判断它是否遵守上面语法,首先从第一个表达式开始,由于最后一个标签是 SEMI,因此它满足第一个表达式右边的 SEMI,现在需要判断 NUMBER PLUS NUMBER 是否能满足 EXPR 的规则。

我们看 EXPR 的右边分解。首先 FACTOR PLUS EXPR 跟 NUMBER PLUS NUMBER 中的 PLUS 匹配,于是接下来需要判断第一个 NUMBER 是否能满足 FACTOR 的规定,同时判断第二个 NUMBER 是否满足 EXPR 规定。

我们看 FACTOR 的分解,它可以直接分解成 NUMBER,所以第一个 NUMBER 满足 FACTOR 的规定,此时再看第二个 NUMBER,由于 EXPR 可以之间分解成 FACTOR,然后 FACTOR 又可以之间分解成 NUMBER,由此第二个 NUMBER 满足 EXPR 规定,至此 NUMBER PLUS NUMBER 能被上面语法解析,因此它包含的标签组合满足给定的语法规则。

上面的推导方法也叫最左推导,因为我们总是先拿到表达式右边,然后从最左往右,依次取出非终结符,先看给定的标签是否满足规范。同时还需要注意的是我们从最顶部的规则开始推导,依次从上往下分解,这种方式也叫自顶向下的推导。后面我们会看到第一种语法解析方式,它的特点是先获得一串标签集合,然后从最左边的标签开始逐个解析,然后采用上面描述的最左推导法,于是这样的语法解析叫 LL语法解析算法,两个 L 都对应英语里的 left,也就是左边的意思。其中LL(1)表示解析时会预先多查看 1 个标签,LL(k)表示预先多查看 k 个标签。之所以预先多查看标签主语是因为一个非终结符可能有多个表达式,例如
EXPR -> FACTOR PLUS EXPR | FACTOR
它其实对应两个表达式,一个是EXPR -> FACTOR PLUS EXPR,另一个是 EXPR->FACTOR,在解析时应该选取哪一个呢,此时就可以通过预先查看 一个或多个标签来决定。后面我们还会研究 LR 解析算法,第一个 L 表示从标签串的最左边开始进行解析,R 表示在解析时采用最右方式,也就是跟我们前面说的最左方式正好相反。

还有一点需要注意的是,在前面给出的语法表达式中,左边的符号都可以解析成右边 1 个或多个符号,事实上还存在一种可能是右边可以解析成 0 个符号,还记得前面将词法解析时的 epsilon 转换吧,它表示当前状态下不需要输入任何符号就能跳转到下一个状态,同样我们允许如下语法表达式
请添加图片描述
此时它表示可以通过什么都不做来完成解析,不难理解c 语言编译器可以编译解析一个内容为空的.c 源文件。

本节描述的东西比较抽象,它很可能给你带来更多的是困惑,好在在最开始和前面做词法解析时,我们都接触过语法解析,所以前面的练习应该会有助于我们对这些理论的理解,在后面章节中,我们会拿几个较为简单的语法解析做练手,通过实践才能更好的帮我们理解和掌握抽象的理论,更多内容请在 b 站搜索 Coding 迪斯尼。

相关文章:

自己动手写编译器:语法解析的基本原理

在前面系列章节中我们完成了词法解析。词法解析的基本任务就是判断给定字符串是否符合特定规则,如果符合那么就给这个字符串分配一个标签(token)。词法解析完成后接下来的工作就要分配给语法解析,后者的任务就是判断一系列标签的组合是否符合特定规范。 …...

VS Code解决乱码

在上边搜索栏输入“>Change File Encoding”,更改编码格式,解决乱码格式。 VS Code会帮助确认编码格式,然后选择就好。 最后完成如下:...

宝塔Linux:部署His医疗项目通过jar包的方式

📚📚 🏅我是默,一个在CSDN分享笔记的博主。📚📚 ​​​ 🌟在这里,我要推荐给大家我的专栏《Linux》。🎯🎯 🚀无论你是编程小白,还是有…...

Vim命令大全(超详细,适合反复阅读学习)

Vim命令大全 Vim简介Vim中的模式光标移动命令滚屏与跳转文本插入操作文本删除操作文本复制、剪切与粘贴文本的修改与替换文本的查找与替换撤销修改、重做与保存编辑多个文件标签页与折叠栏多窗口操作总结 Vim是一款文本编辑器,是Vi编辑器的增强版。Vim的特点是快速、…...

爬虫持久化保存

## open方法- 方法名称及参数markdown **open(file, moder, bufferingNone, encodingNone, errorsNone, newlineNone, closefdTrue)****file** 文件的路径,需要带上文件名包括文件后缀(c:\\1.txt)**mode** 打开的方式(r,w,a,x,b,t…...

统一大语言模型和知识图谱:如何解决医学大模型-问诊不充分、检查不准确、诊断不完整、治疗方案不全面?

统一大语言模型和知识图谱:如何解决医学大模型问诊不充分、检查不准确、诊断不完整、治疗方案不全面? 医学大模型问题如何使用知识图谱加强和补足专业能力?大模型结构知识图谱增强大模型的方法 医学大模型问题 问诊。偏离主诉和没抓住核心。…...

读写分离之同步延迟测试

背景 读写分离是快速提高数据库性能的手段,主库只负责写入,从库负责查询。但在性能得到提升的同时,编程的复杂度就会提升。由其碰到主从同步延迟的情况,在数据写入后,在从库无法读取到最新数据,会对业务逻…...

SpringBoot+OCR 实现PDF 内容识别

一、SpringBootOCR对pdf文件内容识别提取 1、在 Spring Boot 中,您可以结合 OCR(Optical Character Recognition)库来实现对 PDF 文件内容的识别和提取。 一种常用的 OCR 库是 Tesseract,而 pdf2image 是一个用于将 PDF 转换为图…...

Go和Java实现抽象工厂模式

Go和Java实现抽象工厂模式 本文通过简单数据库操作案例来说明抽象工厂模式的使用,使用Go语言和Java语言实现。 1、抽象工厂模式 抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创 建型模式,它…...

深入理解Java虚拟机---内存分配

深入理解Java虚拟机---内存分配 GC日志内存分配与回收策略对象优先在Eden分配大对象直接进入老年代长期存活的对象将进入老年代动态对象年龄判定空间分配担保 GC日志 以下两段典型的GC日志: 33.125: [GC [DefNew: 3324K->152K(3712K), 0.0025925 secs] 3324K-&…...

计算机网络2

OSI参考模型七层: 1.应用层 2.表示层 3.会话层 4.传输层 5.网络层 6.数据链路层 7.物理层 TCP/IP模型 5层参考模型...

jenkins-Generic Webhook Trigger指定分支构建

文章目录 1 需求分析1.1 关键词 : 2、webhooks 是什么?3、配置步骤3.1 github 里需要的仓库配置:3.2 jenkins 的主要配置3.3 option filter配置用于匹配目标分支 实现指定分支构建 1 需求分析 一个项目一般会开多个分支进行开发,测试&#x…...

源码解析8-QSS原理-案例-Qt的qss特殊设置多个子控件的颜色与伪状态

Qt源码解析 索引 源码解析8-QSS原理-案例-Qt的qss特殊设置多个子控件的颜色与伪状态 有些时候我们想特殊设置QSS,比如某一类标题栏目,某一个窗口中的颜色。 重要的是我们需要同时设置多个特殊的按钮等。 统一设置所有 单一按钮全局设置 QPushButton…...

Nginx+Tomcat实现负载均衡和动静分离

目录 前瞻 动静分离和负载均衡原理 实现方法 实验(七层代理) 部署Nginx负载均衡服务器(192.168.75.50:80) 部署第一台Tomcat应用服务器(192.168.75.60:8080) 多实例部署第二台Tomcat应用服务器(192.168.75.70:80…...

linux系统的u盘/mmc/sd卡等的支持热插拔和自动挂载行为

1.了解mdev mdev是busybox自带的一个简化版的udev。udev是从Linux 2.6 内核系列开始的设备文件系统(DevFS)的替代品,是 Linux 内核的设备管理器。总的来说,它取代了 devfs 和 hotplug,负责管理 /dev 中的设备节点。同时…...

使用Python将OSS文件免费下载到本地:项目分析和准备工作

大家好,我是水滴~~ 本文将介绍如何使用Python编程语言将OSS(对象存储服务)中的文件免费下载到本地计算机。我们先进行项目分析和准备工作,为后续的编码及实施提供基础。 《Python入门核心技术》专栏总目录・点这里 文章目录 1. 前…...

从Gitee克隆项目、启动方法

从gitee克隆VUE项目到本地后,不能直接运行,需要进行npm install安装node_modules文件夹里面的内容,因为在git上传的时候,一般都会过滤到node_modules中的依赖文件。 安装依赖以后,启动通过npm run serve启动项目出错。…...

不用再找了,这是大模型实践最全的总结

随着ChatGPT的迅速出圈,加速了大模型时代的变革。对于以Transformer、MOE结构为代表的大模型来说,传统的单机单卡训练模式肯定不能满足上千(万)亿级参数的模型训练,这时候我们就需要解决内存墙和通信墙等一系列问题&am…...

QT 记录

qml 移动窗口会闪烁 int main(int argc, char *argv[]) {QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);//orQCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); }window 拉取qml程序依赖文件 打开QT自带的命令窗口,转到exe程序目录: …...

智能优化算法应用:基于黑寡妇算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于黑寡妇算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于黑寡妇算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.黑寡妇算法4.实验参数设定5.算法结果6.参考文…...

VSCode 常用的快捷键和技巧系列(2)

一、如何让VSCode工程树显示图标 第一步:安装 快捷键 CtrlP ,输入 ext install vscode-icons ,然后点击安装插件 第二步:配置 安装成功后,点击Reload重新加载。 然后配置,当前图标使用VsCode-Icons Go…...

【Hadoop】执行start-dfs.sh启动hadoop集群时,datenode没有启动怎么办

执行start-dfs.sh后,datenode没有启动,很大一部分原因是因为在第一次格式化dfs后又重新执行了格式化命令(hdfs namenode -format),这时主节点namenode的clusterID会重新生成,而从节点datanode的clusterID 保持不变。 在…...

计算机网络(四)

九、网络安全 (一)什么是网络安全? A、网络安全状况 分布式反射攻击逐渐成为拒绝攻击的重要形式 涉及重要行业和政府部门的高危漏洞事件增多。 基础应用和通用软硬件漏洞风险凸显(“心脏出血”,“破壳”等&#x…...

非递归实现的快速排序

目录 序列文章 前言 学前补充 非递归快速排序 注意事项(重要) 实现步骤 代码实现 时空复杂度 快速排序的特性 栈的相关代码 序列文章 非递归实现的快速排序:http://t.csdnimg.cn/UEcL6 快速排序的挖坑法与双指针法:ht…...

windows 安装jenkins

下载jenkins 官方下载地址:Jenkins 的安装和设置 清华源下载地址:https://mirrors.tuna.tsinghua.edu.cn/jenkins/windows-stable/ 最新支持java8的版本时2.346.1版本,在清华源中找不到,在官网中没找到windows的下载历史&#xff…...

SQL进阶理论篇(十二):InnoDB中的MVCC是如何实现的?

文章目录 简介事务版本号行记录的隐藏列Undo LogRead View的工作流程总结参考文献 简介 在不同的DBMS里,MVCC的实现机制是不同的。本节我们会以InnoDB举例,讲解InnoDB里MVCC的实现机制。 我们需要掌握这么几个概念: 事务版本号行记录的隐藏…...

SpringCloudAliBaba篇之Seata:分布式事务组件理论与实践

1、事务简介 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中,一个事务由一组SQL语句组成,事务具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID原则。 原子性(atomici…...

在centos7.9上安装Jenkins的安装过程

1.jenkins的安装和配置: 安装JDK: yum install -y fontconfig java-11-openjdk # 安装目录:/usr/lib/jvm # fontconfig 是 Linux 系统中用于配置和管理字体的一种工具 下载jenkins安装包: sudo wget -O /etc/yum.repos.d/jenkins…...

uni-app基本标签

导航栏设置 - navigationBarBackgroundColor: 设置导航栏的背景颜色(全局页面) - navigationBarTextStyle: 导航栏标题颜色(仅支持 black 和 white) - navigationBarTitleText: 设置导航栏标题内容 - enablePullDownRefresh: 是否…...

《PySpark大数据分析实战》-14.云服务模式Databricks介绍基本概念

📋 博主简介 💖 作者简介:大家好,我是wux_labs。😜 热衷于各种主流技术,热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员(PCTA)、TiDB数据库专家(PCTP…...