当前位置: 首页 > 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.参考文…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

条件运算符

C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解

文章目录 一、开启慢查询日志&#xff0c;定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...

Linux安全加固:从攻防视角构建系统免疫

Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践

01技术背景与业务挑战 某短视频点播企业深耕国内用户市场&#xff0c;但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大&#xff0c;传统架构已较难满足当前企业发展的需求&#xff0c;企业面临着三重挑战&#xff1a; ① 业务&#xff1a;国内用户访问海外服…...

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...