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

在阅读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运算符/象牙运算符)。作用是给变量赋值并返回表达式的值。

(1)Python所有方向的学习路线(新版)

这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

最近我才对这些路线做了一下新的更新,知识体系更全面了。

在这里插入图片描述

(2)Python学习视频

包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。

在这里插入图片描述

(3)100多个练手项目

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。

在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值