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 浏览器…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
TJCTF 2025
还以为是天津的。这个比较容易,虽然绕了点弯,可还是把CP AK了,不过我会的别人也会,还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...
Element-Plus:popconfirm与tooltip一起使用不生效?
你们好,我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip,产品要求是两个需要结合一起使用,也就是鼠标悬浮上去有提示文字,并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...
