社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

BNF 语法:揭开 Python 语法规则的秘密

Python猫 • 3 周前 • 38 次点击  

请给“Python猫”加星标 ,以免错过文章推送

大家好,我是猫哥。先打个小广告: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可以精确描述编程语言。

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

  • • Terminals(终止符):必须与输入中的特定项完全匹配的字符串。例:"def""return":"

  • • Nonterminals(非终止符):会被替换为具体值的符号。也可称为句法变量(syntactic variables)。例:

  • • Rules(规则):定义terminalsNonterminals的联系。如: ::= "a"

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

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

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

BNF规则及其组成部分

BNF规则的格式通常如下:

 ::= expression

其中

  • • :符号是一个非终止符变量,通常用<>括起来。

  • • ::=:表示左边的非终止符会被右边的表达式替换。

  • • expression:表达式由一系列终止符、非终止符和其它符号组成。

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

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

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

一般示例:全名的语法

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

 ::=  " " ( " ")? 

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

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

我们还需要定义的规则。

  • • 只接受字母

  • • 首字母大写,其余小写

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

 ::= [A-Z]
 ::= [a-z]

接着,我们可以定义的规则:

       ::=  *

您可以按照相同的模式来构建  和  规则。

我们构建完了一个full name的BNF规则。下面我们在BNF Playground网站中测试这个规则。

bnf playground

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

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

  • • 第一个字符是字母、下划线。

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

可以写出相应的BNF规则:

 ::=  ( | )*

其中进一步定义:

       ::= [A-Z] | [a-z] | "_"
      ::= [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([123]))
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 = 5

for number in range(high):
    if number > 5:
        break
    print(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. 1. 熟悉BNF表示法。可以编写BNF规则并在BNF Playground网站中测试。

  2. 2. 了解Python的BNF变体。

  3. 3. 分解规则。将规则分成多个部分来阅读。

  4. 4. 识别非终止符。非终止符可能需要进一步阅读。

  5. 5. 了解终止符。查找表示语言中特定元素的终止符,例如关键字、运算符、文本或标识符。这些符号被引号括起来。

  6. 6. 结合实例:研究与您试图理解的 BNF 规则相对应的实际示例。分析 BNF 规则如何应用于这些示例。将规则与实际的 Python 语法进行对比。


如果你觉得本文有帮助
请慷慨分享点赞,感谢啦

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/169873
 
38 次点击