Python:词法分析(行结构与显式、隐式行拼接)
相关阅读
Python
https://blog.csdn.net/weixin_45791458/category_12403403.html?spm=1001.2014.3001.5482
1、逻辑结构
一个Python程序由许多逻辑行组成,字面意义上的一行指的是末尾有换行符(\n),但在不同的情况下,行末尾的换行符(\n)可能有不同的意义。
2、逻辑行
逻辑行的结尾的换行符(\n)被解析为NEWLINE标记。一般来说,一条语句不能跨越逻辑行而存在(除非是复合语句,如if复合语句可以由多个逻辑行组成)。根据显式或隐式行拼接规则,若干个物理行可以组成逻辑行。
3、物理行
物理行的结尾的换行符(\n)可能被解析为NEWLINE标记(如果这个物理行是一个逻辑行中的最后一个物理行),或者NL标记(如果这个物理行不是一个逻辑行中的最后一个物理行),或者也可能在显式行拼接时与反斜杠(\)一起被删除。
4、注释
注释是一种特殊的逻辑行,对于单行是完全的注释,它末尾的换行符(\n)会被解析为NL标记。而一个位于逻辑行末尾的注释,它末尾的换行符(\n)则会被解释为NEWLINE标记。但无论是哪种解释,注释代表着从#到换行符(\n)之间的内容(不包括换行符(\n))会被解析为一个整体,即注释标记而对程序无任何影响。
5、显式行拼接
两个及两个以上的物理行可用反斜杠(\)拼接为一个逻辑行,规则如下:除了注释中的反斜杠(\)加换行符(\n)结尾外(因为这时的反斜杠(\)已经被当做了注释,这也代表着注释无论如何不会影响到下一行),物理行将与从上到下一次拼接直到一个逻辑行,并删除末尾的反斜杠(\)及其后的换行符(\n),当使用反斜杠(\)时,末尾不允许有注释,因为这样反斜杠(\)后面就没有换行符(\n)也就无法行拼接了。需要注意的是,显式行拼接无法拼接除字符串字面量外的标记,而后面谈到的的隐式拼接无法拼接任何标记,标记即一个解析的整体,例如:函数print是一个标记,字符串"aaa"是一个标记,而1 + 1包含三个标记,因为其中不属于行首的空格、制表符等空白符不会被解析为标记,而行首的空格、制表符被解析为缩近标记。
下面来看几个例子:
if 1900 < year < 2100 and 1 <= month <= 12 \and 1 <= day <= 31 and 0 <= hour < 24 \and 0 <= minute < 60 and 0 <= second < 60: # 这里的注释是允许的,而上两行末尾再加注释是不允许的,因为这样\后面就没有换行符了return 1#正确的显式行拼接,因为并没有分割任何标记
a = 1 + \
2 #错误的显式行拼接,因为分割了标记,语法分析时会产生错误解析
pr\
int("hello world!")#正确的显式行拼接,虽然字符串"aaa"是一个标记,但这是唯一的例外
a = "aa\
a"
如何更加直观的验证上面的这些分析有什么方法吗?当然有,tokenize包可以帮助我们解析一串代码,下面给出一段测试程序。
import tokenize
from io import BytesIOcode = """The code you are testing"""# 将代码字符串转换为字节流
code_bytes = code.encode('utf-8')
code_stream = BytesIO(code_bytes)# 使用tokenize.tokenize生成tokens
tokens = tokenize.tokenize(code_stream.readline)# 遍历tokens并打印信息
for token in tokens:print(token)
根据自己的需要,你可以将任何一段程序粘贴进上面的相应位置进行验证,使用三引号(""")的原因是它能保留跨行字符串而不使用反斜杠(\)。这很重要,因为如果使用双引号("),则无法测试下一节没有反斜杠(\)的隐式行连接,因为这代表着没有反斜杠(\)的字符串被分成了两行,但上面说过隐式行连接无法拼接任何标记,所以甚至连测试程序都无法通过语法分析,下面我们看一个测试结果。
import tokenize
from io import BytesIOcode = """a = 1 + \
2"""# 将代码字符串转换为字节流
code_bytes = code.encode('utf-8')
code_stream = BytesIO(code_bytes)# 使用tokenize.tokenize生成tokens
tokens = tokenize.tokenize(code_stream.readline)# 遍历tokens并打印信息
for token in tokens:print(token)TokenInfo(type=62 (ENCODING), string='utf-8', start=(0, 0), end=(0, 0), line='')
TokenInfo(type=1 (NAME), string='a', start=(1, 0), end=(1, 1), line='a = 1 + 2')
TokenInfo(type=54 (OP), string='=', start=(1, 2), end=(1, 3), line='a = 1 + 2')
TokenInfo(type=2 (NUMBER), string='1', start=(1, 4), end=(1, 5), line='a = 1 + 2')
TokenInfo(type=54 (OP), string='+', start=(1, 6), end=(1, 7), line='a = 1 + 2')
TokenInfo(type=2 (NUMBER), string='2', start=(1, 8), end=(1, 9), line='a = 1 + 2')
TokenInfo(type=4 (NEWLINE), string='', start=(1, 9), end=(1, 10), line='')
TokenInfo(type=0 (ENDMARKER), string='', start=(2, 0), end=(2, 0), line='')
从上面的解析结果可以看出,确实两物理行被拼接成了一逻辑行,而末尾的反斜杠(\)与换行符(\n)消失所以没有解析成标记。
6、显式行拼接
隐式拼接的圆括号、方括号、花括号内的表达式可以分成多个物理行,不必使用反斜杠。例如:
month_names = ['Januari', 'Februari', 'Maart', # 这里'April', 'Mei', 'Juni', # 可以'Juli', 'Augustus', 'September', # 加注释'Oktober', 'November', 'December'] # 这并不会有影响#正确的隐式行拼接,没有分隔标记
a = (1 +
2)#正确的隐式行拼接,没有分隔标记
a = [1,
2]#正确的隐式行拼接,没有分隔标记
a = {1,
2}#错误的隐式行拼接,分隔了标记
prin
t("hello world!")
下面我们看一个测试结果:
import tokenize
from io import BytesIOcode = """a = (1 +
2)"""# 将代码字符串转换为字节流
code_bytes = code.encode('utf-8')
code_stream = BytesIO(code_bytes)# 使用tokenize.tokenize生成tokens
tokens = tokenize.tokenize(code_stream.readline)# 遍历tokens并打印信息
for token in tokens:print(token)TokenInfo(type=62 (ENCODING), string='utf-8', start=(0, 0), end=(0, 0), line='')
TokenInfo(type=1 (NAME), string='a', start=(1, 0), end=(1, 1), line='a = (1 +\n')
TokenInfo(type=54 (OP), string='=', start=(1, 2), end=(1, 3), line='a = (1 +\n')
TokenInfo(type=54 (OP), string='(', start=(1, 4), end=(1, 5), line='a = (1 +\n')
TokenInfo(type=2 (NUMBER), string='1', start=(1, 5), end=(1, 6), line='a = (1 +\n')
TokenInfo(type=54 (OP), string='+', start=(1, 7), end=(1, 8), line='a = (1 +\n')
TokenInfo(type=61 (NL), string='\n', start=(1, 8), end=(1, 9), line='a = (1 +\n')
TokenInfo(type=2 (NUMBER), string='2', start=(2, 0), end=(2, 1), line='2)')
TokenInfo(type=54 (OP), string=')', start=(2, 1), end=(2, 2), line='2)')
TokenInfo(type=4 (NEWLINE), string='', start=(2, 2), end=(2, 3), line='')
TokenInfo(type=0 (ENDMARKER), string='', start=(3, 0), end=(3, 0), line='')
从上面的解析结果可以看出,第一行末尾的换行符(\n)被解析为NL标记,而第二行末尾的换行符(\n)被解析为NEWLINE标记。对于上文谈到的其他特性和结果,可以自行使用程序进行测试,在此不进行详述。
相关文章:
Python:词法分析(行结构与显式、隐式行拼接)
相关阅读 Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 1、逻辑结构 一个Python程序由许多逻辑行组成,字面意义上的一行指的是末尾有换行符(\n),但在不同的情况下,行末尾的换行符(\n)可能有…...
前端Vue 结合xlxs库实现解析excel文件,并动态组装表头!
目录 1.前言2.数据定义3. 页面布局4.上传之前的事件5.解析excel文件,并组装系统表头与excel表头的对应关系6.下拉框改变事件 1.前言 最近有一个需求,就是用户可以任意导入一个自定义的excel文件,让用户可以自己选择,组装表头的对应关系&…...
RabbitMQ集群配置以及负载均衡配置
RabbitMQ集群配置以及负载均衡配置 环境配置集群配置安装rabbitmq启动rabbitmq开启远程登录添加用户并且授权用户添加数据存放目录和日志存放目录查看端口拷⻉erlang.cookie将mq-2、mq-3作为内存节点加⼊mq-1节点集群中查看集群状态添加一个新的队列 RabbitMq负载均衡配置-HAPr…...
Leetcode Hot100之六:42.接雨水
题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 提示: n height.length 1 < n < 2 * 10^4 0 < height[i] < 10^5 思路 暴力循环: 原本的思路是左边界i从左到…...
electron 主进程 和 渲染进程通信 ipcRenderer 和 mainWindow.webContents
electron 开发时最麻烦就是electron版本和node版本的选择和正确安装 electron 用npm安装时太慢容易报错,建议用cnpm i 进行安装 注意最新版渲染进程使用node nodeIntegration: true, // 渲染进程可用node contextIsolation: false, // 这个值影响nodeIntegration是…...
关于VUE启动内存溢出
安装node v10.14.2 后 启动公司的VUE项目 使用命令npm run dev 命令 报错: <--- Last few GCs --->[20940:00000244699848E0] 215872 ms: Scavenge 1690.2 (1836.4) -> 1679.6 (1836.4) MB, 5.4 / 0.7 ms (average mu 0.266, current mu 0.253) a…...
HBase学习笔记(1)—— 知识点总结
目录 HBase概述 HBase 基本架构 HBase安装部署启动 HBase Shell HBase数据读写流程 HBase 优化 HBase概述 HBase是以 hdfs 为数据存储的,一种分布式、非关系型的、可扩展的 NoSQL 数据库 关系型数据库和非关系型数据库的区别: 关系型数据库和非关…...
【Linux】 awk命令使用
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。 语法 awk [选项] [文件] awk [选项] [程序] [文件] awk命令 -Linux手…...
Sentinel网关限流
背景 在微服务架构下,每个服务的性能都不同,为避免出现流量洪峰将服务冲垮,需要依赖限流工具来保护服务的稳定性。sentinel是阿里提供的限流工具,社区活跃,功能也很全面,包含实时监控、流控、熔断等功能。…...
solidworks对电脑要求高吗?2023solidworks配置要求
solidworks对电脑要求高吗?SolidWorks是一款功能强大的三维CAD软件,对电脑配置有一定的要求。一般来说,运行SolidWorks需要的电脑配置包括较高的处理器性能、足够的内存和存储空间,以及一块性能良好的显卡。此外,对于大…...
搭建神经网络(torch.nn的用法)
零零碎碎总结了一些torch框架里面nn模块的用法,尤其是关于搭建神经网络的 nn.ModuleList nn.Module nn.Sequential nn.Linear nn.Dropout nn.Embedding nn.DataParallel() 将模型封装起来,便于在多个gpu上并行计算,训练或者推理 nn.…...
卡码网语言基础课 | 11. 句子缩写
目录 一、 字符串大小的比较 二、 ASCII码值 三、 基本框架代码 四、 解题思路 4.1 首字母问题 4.2 判定小写字母 4.3 小写字母转换为大写字母 五、空格判断 六、 代码模块化 6.1 满足的条件 6.2 代码完善 七、 题目解答 7.1 原始代码 7.2 改进代码 八、 拓展与…...
Surface RT 安装 Linux
零:起因 在家无事找出来一台老旧设备 Surface RT 一代的,系统最新是 Windows 8.1 arm版,应用商店都已经打不开了 虽说有破解方法,能运行些软件,但怎么说也不是任意安装,所以局限性还是相当的大࿰…...
C++中的函数重载:多功能而强大的特性
引言 函数重载是C编程语言中的一项强大特性,它允许在同一个作用域内定义多个同名函数,但这些函数在参数类型、个数或顺序上有所不同。本文将深入探讨函数重载的用法,以及它的优势和应用场景。 正文 在C中,函数重载是一项非常有…...
数据分析实战 | K-means算法——蛋白质消费特征分析
目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 编辑 八、模型评价 九、模型调参与预测 一、数据及分析对象 txt文件——“protein.txt”,主要记录了25个国家的9个属性,主…...
HTTP协议详解-下(Tomcat)
如何构造 HTTP 请求 对于 GET 请求 地址栏直接输入点击收藏夹html 里的 link script img a…form 标签 通过 form 标签构造GET请求 <body><!-- 表单标签, 允许用户和服务器之间交互数据 --><!-- 提交的数据报以键值对的结果来组织 --><form action&quo…...
acwing算法基础之搜索与图论--prim算法
目录 1 基础知识2 模板3 工程化 1 基础知识 朴素版prim算法的关键步骤: 初始化距离数组dist,将其内的所有元素都设为正无穷大。定义集合S,表示生成树。循环n次:找到不在集合S中且距离集合S最近的结点t,用它去更新剩余…...
Amazon EC2 Serial Console 现已在其他亚马逊云科技区域推出
即日起,交互式 EC2 Serial Console 现也在以下区域推出:中东(巴林)、亚太地区(雅加达)、非洲(开普敦)、中东(阿联酋)、亚太地区(香港)…...
hdlbits系列verilog解答(100输入逻辑门)-39
文章目录 一、问题描述二、verilog源码三、仿真结果一、问题描述 构建一个具有 100 个输入in[99:0]的组合电路。 有 3 个输出: out_and: output of a 100-input AND gate. out_or: output of a 100-input OR gate. out_xor: output of a 100-input XOR gate. 二、verilog源…...
Python 中 Selenium 的屏幕截图
文章目录 使用 save_screenshot() 函数在 Python 中使用 selenium 捕获屏幕截图使用 get_screenshot_as_file() 函数在 Python 中使用 selenium 捕获屏幕截图使用 Screenshot-Selenium 包在 Python 中使用 selenium 捕获屏幕截图总结我们可以使用 Selenium 在自动化 Web 浏览器…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
