[译]BNF 表示法:深入了解 Python 的语法

[译]BNF 表示法:深入了解 Python 的语法

原文:《BNF Notation: Dive Deeper Into Python’s Grammar》
https://realpython.com/python-bnf-notation/

在阅读Python文档的时候,你可能已经遇到过BNF(Backus–Naur form)表示法:
文档中的BNF

下面我们将了解BNF表示法,以及如何使用它来理解Python的语法。

理解BNF表示法

BNF是上下文无关语法的元语法符号。计算机科学家经常使用这种符号来描述编程语言的语法,因为它允许他们编写语言语法的详细描述。

BNF 符号由三个核心部分组成:

  • Terminals(终止符):必须与输入中的特定项完全匹配的字符串。例:"def", "return, ":"
  • Nonterminals(非终止符):会被替换为具体值的符号。也可称为句法变量(syntactic variables)。例:<letter>, <digit>
  • Rules(规则): 定义terminalsNonterminals的联系。 如:<letter> ::= "a"

通过组合终止符非终止符,可以创建出BNF 规则

通过定义一组规则,可以构建出一个语言的语法(grammar)。

BNF具有一些变体,如EBNF和ABNF。

BNF规则及其组成部分

BNF规则的格式通常如下:

<symbol> ::= expression

其中

  • <symbol>:符号是一个非终止符变量,通常用<>括起来。
  • ::=: 表示左边的非终止符会被右边的表达式替换。
  • expression:表达式由一系列终止符、非终止符和其它符号组成。

在构建BNF规则时,你可以定义一些符号表示不同含义,例如:

符号含义
""将终止符括起来
<>表示非终止符
()表示一组有效选项
+指定上一个元素中的一个或多个
*…零个或多个
?…零个或一个
|选择其中一个
[x-z]字母或数字区间

下面我们尝试自定义一些BNF规则。

一般示例:全名的语法

现在我们尝试定义一个人的全名的语法,一个人的全名包含3部分:
first name, middle name, family name
每个部分之间应该用空格分隔,middle name是可选的。

<full_name> ::= <first_name> " " (<middle_name> " ")? <family_name>

规则的左侧部分是一个非终止符变量,用于标识人员的全名。::= 符号表示 <full_name> 将替换为规则的右侧部分。

规则的右侧部分有几个组成部分。首先是first name,使用<first_name>非终止符定义。
接下来是一个空格。为了定义空格,要使用一个终止符,即" "
接下来,我们有一个可选的middle_name,使用(<middle_name> " ")?定义。
最后,我们有一个家庭名,使用<family_name>定义。

我们还需要定义<first_name>, <middle_name>, <family_name>的规则。

  • 只接受字母
  • 首字母大写,其余小写

我们又引入了大写字母和小写字母两个非终止符,需要进一步定义:

<uppercase_letter> ::= [A-Z]
<lowercase_letter> ::= [a-z]

接着,我们可以定义<first_name>, <middle_name>, <family_name>的规则:

<first_name>       ::= <uppercase_letter> <lowercase_letter>*

您可以按照相同的模式来构建 <middle_name><family_name> 规则。

我们构建完了一个full name的BNF规则。
下面我们在BNF Playground网站中测试这个规则。
在这里插入图片描述

与编程相关的示例:标识符

在学习编程语言时,我们很早就会接触到标识符(Identifiers)的概念。
标识符是用来标识变量、函数、类等的名称。
在Python中,标识符的命名规则如下:

  • 第一个字符是字母、下划线。
  • 其余字符可以是字母、下划线或数字。

可以写出相应的BNF规则:

<identifier> ::= <char> (<char> | <digit>)*

其中<char><digit>进一步定义:

<char>       ::= [A-Z] | [a-z] | "_"
<digit>      ::= [0-9]

我们可以在BNF Playground网站中测试这个规则。

Python的BNF变体

Python 使用 BNF 表示法的自定义变体来定义语言的语法。

Python 的 BNF 变体使用以下样式:

符号含义
name规则或非终止符的名称
::=意味着
``
*零个或多个
+一个或多个
[]零个或一个,即可选项
()分组
|文本字符串
space仅对分隔令牌有意义

这些符号定义了 Python 的 BNF 变体。与常规 BNF 规则的一个显着区别是Python不使用尖括号( <> )来括起非终端符号。它仅使用非终端标识符或名称。这使得规则更简洁易读。
另外,[]的含义不再是字符集,而是可选项。要定义类似于BNF的[a-z],需要使用"a"..."z"

在Python文档经常会遇到BNF代码片段,有必要学习如何阅读它们。

从 Python 的文档中读取 BNF 规则:示例

pass 和 return 语句

这是Python的pass语句

pass_stmt ::=  "pass"

这里,pass_stmt是一个规则的名称,使用::=指示规则扩展为"pass""pass"是一个终止符,意味着语句本身由单词pass组成。
因此,pass语句只是一个单词

pass

另一个常见的语句是return语句:

return_stmt ::= "return" [expression_list]

return语句由"return"[expression_list]组成。expression_list是一个非终止符,[]表示它是可选的。

因此你可以这样使用return语句

def func():return

如果你进入expression_list的定义,你会看到

expression_list ::= expression ("," expression)* [","]

又出现了一个非终止符expression,你可以继续查看expression的定义。

通过该定义,你可以了解到return语句可以返回一个或多个(用,隔开)表达式。

def func():return "Hello!", "Pythonista!"

赋值表达式

Python 3.8 引入了赋值表达式:=(称为walrus运算符/象牙运算符)。作用是给变量赋值并返回表达式的值。

assignment_expression ::=  [identifier ":="] expression

规则的右侧先是一个可选的组件,由一个标识符和一个终止符:=组成。然后是一个表达式。

我们可以在python中使用赋值表达式:

identifier := expression

例如

>>> (length := len([1, 2, 3]))
3
>>> length
3

条件语句

我们现在进阶到复合语句了。
if语句的BNF规则如下:

if_stmt ::=  "if" assignment_expression ":" suite("elif" assignment_expression ":" suite)*["else" ":" suite]

首先是终止符if,然后是assignment_expression(上一节已经讨论过)。然后是终止符:, 非终止符suite
安装刚刚读的定义,我们可以写出下面的if语句:

if assignment_expression:suite

继续看定义,我们有了可选的elif:

if assignment_expression:suite
elif assignment_expression:suite

最后是可选的else:

if assignment_expression:suite
elif assignment_expression:suite
else:suite

循环语句

循环是 Python 中另一个常用的复合语句。Python中有两种循环:

  • for循环
  • while循环

for 循环的 BNF 语法如下:

for_stmt ::=  "for" target_list "in" starred_list ":" suite["else" ":" suite]

于是我们可以写出for语句:

for target_list in starred_list:suite
else:suite

例如:

high = 5for number in range(high):if number > 5:breakprint(number)
else:print("range covered")

while 循环的 BNF 语法如下:

while_stmt ::=  "while" assignment_expression ":" suite["else" ":" suite]

可以写出while语句:

while assignment_expression:suite
else:suite

读取 Python BNF 的最佳实践

当您阅读文档中的 Python 的 BNF 规则时,您可以遵循一些最佳实践来提高您的理解。以下是一些建议:

  1. 熟悉BNF表示法。可以编写BNF规则并在BNF Playground网站中测试。
  2. 了解Python的BNF变体。
  3. 分解规则。将规则分成多个部分来阅读。
  4. 识别非终止符。非终止符可能需要进一步阅读。
  5. 了解终止符。 查找表示语言中特定元素的终止符,例如关键字、运算符、文本或标识符。这些符号被引号括起来。
  6. 结合实例:研究与您试图理解的 BNF 规则相对应的实际示例。分析 BNF 规则如何应用于这些示例。将规则与实际的 Python 语法进行对比。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/721598.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动化测试摸索:python+selenium+pytest(持续更新.....)

一、环境搭建 1、python 安装 下载链接&#xff1a;Python Releases for Windows | Python.org 自己选择合适的版本下载 当下载完毕时&#xff0c;找到该安装程序&#xff1a;python-3.12.2-amd64.exe文件&#xff0c;双击启动安装向导。 为了防止C:盘文件因系统故障或者无…

鸿蒙 Stage模型-AbilityStage、Context、Want

前提&#xff1a;基于官网3.1/4.0文档。参考官网文档 基于Android开发体系来进行比较和思考。&#xff08;或有偏颇&#xff0c;自行斟酌&#xff09; 一、 AbilityStage 1.概念 AbilityStage是一个Module级别的组件容器&#xff0c;应用的HAP在首次加载时会创建一个AbilitySt…

融资项目——nacos注册中心

1.在分布式微服务架构中&#xff0c;注册中心是核心的基础服务之一。 2.服务治理的实现主要依靠的就是注册中心&#xff0c;用来进行服务的发现与注册。 一、服务注册 就是将提供某个服务的模块信息(通常是这个服务的ip和端口)注册到注册中心上去。例如B服务在某些服务器上线…

租房招聘平台新篇章:Java+SpringBoot技术革新

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

k8s-prometheus应用监控 23

使用prometheus监控&#xff0c;结合prometheus传递的指标&#xff0c;从而实现业务监控的自动化弹缩。 注&#xff1a;部署集群需要消耗较大的内存&#xff0c;需要提前扩容各节点的内存量至少达到4g 部署一个用于被监控的应用 上传所需镜像 修改yaml文件 部署完成 没有就绪是…

Linux检查软件信息及Linux清理日志等功能

提示:工具下载链接在文章最后 目录 一.ywtool check命令1.1 ywtool check -I1.2 ywtool check all1.3 ywtool check io1.4 ywtool check elk1.5 ywtool check php1.6 ywtool check mysql1.7 ywtool check nginx1.8 ywtool check system1.9 ywtool check docker_nbip [容器名称]…

MyCAT集群——MyCAT2如何配置读写分离

先搭载MySQL一主两从 192.168.20.110MyCAT192.168.20.111Master192.168.20.112slave1192.168.20.113slave2 配置就不写了&#xff0c;比较基础&#xff0c;写一下步骤 1.进入mysql配置文件或者其子配置文件&#xff0c;添加server_id,开启gtidgtid_modeON,enforce-gtid-cons…

STM32:CAN功能板设计和调试

0前言 本文主要目的是&#xff0c;总结去年设计stm32-CAN板子过程中遇到的问题&#xff0c;分为keil嵌入式软件和嘉立创EDA设计两个部分。 1 STM32F1 CAN功能 keil expected a “}“ 问题在于&#xff0c;PCB使用芯片为stm32f103c8t6&#xff0c;下载程序时选择device默认此…

项目部署发布

目录 上传数据库 修改代码中的数据源配置 修改配置文件中的日志级别和日志目录 打包程序 ​编辑​编辑 上传程序 查看进程是否在运行 以及端口 云服务器开放端口(项目所需要的端口) 上传数据库 通过xshell控制服务器 创建目录 mkdir bit_forum 然后进入该目录 查看路…

012 Linux_线程控制

前言 本文将会向你介绍线程控制&#xff08;创建&#xff08;请见上文&#xff09;&#xff0c;终止&#xff0c;等待&#xff0c;分离&#xff09; 线程控制 线程终止 pthread_t pthread_self(void); 获取线程自身的ID 如果需要只终止某个线程而不终止整个进程,可以有三种…

【C语言】Leetcode 206.反转链表

博主主页&#xff1a;17_Kevin-CSDN博客 收录专栏&#xff1a;《Leetcode》 题目 解决思路 思路一&#xff1a;翻转链表 struct ListNode* reverseList(struct ListNode* head) {if(head NULL){return NULL;}struct ListNode* n1 NULL,*n2 head,*n3 n2 -> next;while(…

线上问题——学习记录幂等判断失效问题分析

一、业务流程 上图是对save和saveScore两个接口的流程抽象&#xff0c;save是上传答题数据&#xff0c;saveScore则是上传答题分数&#xff0c;为保证幂等和防止并发调用&#xff0c;这两个接口都加了分布式锁&#xff08;还是两层哦&#xff09;。第一层使用的是不同的锁&…

【笔记】Android 漫游定制SPN定制有关字段

一、SPN模块简介 【笔记】SPN和PLMN 运营商网络名称显示 Android U 配置 WiFiCalling 场景下PLMN/SPN 显示的代码逻辑介绍 【笔记】Android Telephony 漫游SPN显示定制&#xff08;Roaming Alpha Tag&#xff09; 二、相关配置字段 non_roaming_operator_string_array 是否…

共筑前端学习之路:欢迎加入我们的前端组件学习交流群

共筑前端学习之路&#xff1a;欢迎加入我们的前端组件学习交流群 随着信息技术的飞速发展&#xff0c;前端开发作为构建数字化世界的重要一环&#xff0c;越来越受到广大开发者的关注和重视。为了更好地服务于前端开发者&#xff0c;尤其是那些对前端组件充满热情的粉丝&#x…

【Leetcode每日一题】 前缀和 - 除自身以外数组的乘积(难度⭐⭐)(26)

1. 题目解析 题目链接&#xff1a;238. 除自身以外数组的乘积 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于计算题目所给数组除本身外其他元素的积的数组返回即可。 2. 算法原理 为了计算每个位置i的最终结果ret[i]&…

基于java springboot+redis网上水果超市商城设计和实现以及文档

基于java springbootredis网上水果超市商城设计和实现以及文档 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留…

Day17:信息打点-APP资产知识产权应用监控静态提取动态抓包动态调试

目录 案例1&#xff1a;名称获取APP信息&#xff08;爱企查/小蓝本/七麦/点点&#xff09; 案例2&#xff1a;URL网站备案查APP 案例3&#xff1a;APP提取信息-静态分析 案例3&#xff1a;APP提取信息-动态抓包 案例4&#xff1a;APP提取信息-动态调试 思维导图 章节知识…

Centos8 yum方式安装Redis

Centos8 yum方式安装多个Redis 是否安装GCC依赖 ggc -v #或者 rpm -q gcc安装GCC yum install -y gcc如果不是管理员 加 sudo sudo yum install -y gcc yum安装Redis yum install redis失败更新yum 再安装 #添加EPEL仓库 sudo yum install epel-release#更新yum源 sudo yum upd…

智能电网监控:图像分类技术在能源电力领域的创新应用

一、引言 在当今这个对能源效率要求日益增长的时代&#xff0c;电力行业正面临着前所未有的挑战。为了满足日益增长的电力需求&#xff0c;同时确保电网的稳定性和可靠性&#xff0c;我们采用了一种革命性的方法&#xff1a;通过智能算法和自动化技术来优化电网的运行。这一项…

网络学习:SMart link技术与Monitor link技术

目录 一、SMart link技术 1.1、SMart link技术简介 1.2、SMart link技术原理及基础知识点 1、应用场景&#xff08;举例&#xff09;&#xff1a; 2、运行机制 3、保护vlan 4、控制VLAN 5、Flush报文 6、SMart link的负载分担机制 7、SMart link角色抢占模式 二、Mo…