0

0

深入理解Python赋值语句的BNF结构

霞舞

霞舞

发布时间:2025-09-01 21:39:01

|

281人浏览过

|

来源于php中文网

原创

深入理解Python赋值语句的BNF结构

本文旨在深入解析Python赋值语句的巴科斯-诺尔范式(BNF)结构,特别是针对初学者常遇到的困惑:一个简单的数字字面量(如9)如何符合复杂的右侧表达式语法。通过详细追溯从starred_expression到literal的完整解析路径,并强调BNF中可选语法元素的设计,揭示Python语法解析的内在机制。

Python赋值语句的BNF核心结构

python语言的语法规则由其官方文档中定义的巴科斯-诺尔范式(bnf)所描述。赋值语句是python中最基本的操作之一,其bnf定义如下:

assignment_stmt ::=  (target_list "=")+ (starred_expression | yield_expression)
target_list     ::=  target ("," target)* [","]
target          ::=  identifier
                     | "(" [target_list] ")"
                     | "[" [target_list] "]"
                     | attributeref
                     | subscription
                     | slicing
                     | "*" target

从上述定义中可以看出,一个赋值语句(assignment_stmt)由一个或多个目标列表(target_list)和一个等号(=)组成,其右侧(RHS)则是一个starred_expression或yield_expression。例如,在a = 9这个简单的赋值中,a是target_list的一部分,而9则必须符合starred_expression或yield_expression的语法。

右侧表达式的解析路径:从starred_expression到expression

对于a = 9这样的普通赋值,右侧的9显然不是一个yield_expression(它涉及生成器),因此它必须符合starred_expression的定义。starred_expression的BNF定义如下:

starred_expression ::=  expression | (starred_item ",")* [starred_item]
starred_item       ::=  assignment_expression | "*" or_expr

这里是理解9如何符合语法的关键点:starred_expression可以仅仅是一个expression。这意味着,只要9能够被解析为一个expression,它就能作为赋值语句的右侧部分。因此,我们的核心任务就变成了追溯expression如何最终包含像9这样的数字字面量。

逐步深入:从expression到literal

Python的expression是一个非常广泛的概念,它通过一系列的递归定义,逐步细化到最基本的语法单元,如字面量(literal)。下面是expression到integer的完整解析路径:

立即学习Python免费学习笔记(深入)”;

  1. expression: 可以是 conditional_expression 或 lambda_expr。

    expression             ::=  conditional_expression | lambda_expr

    9 不含 lambda,所以它被解析为 conditional_expression。

  2. conditional_expression: 可以是 or_test ["if" or_test "else" expression]。

    conditional_expression ::=  or_test ["if" or_test "else" expression]

    9 不含 if/else,所以它被解析为 or_test。

  3. or_test: 可以是 and_test 或 or_test "or" and_test。

    or_test                ::=  and_test | or_test "or" and_test

    9 不含 or,所以它被解析为 and_test。

  4. and_test: 可以是 not_test 或 and_test "and" not_test。

    and_test               ::=  not_test | and_test "and" not_test

    9 不含 and,所以它被解析为 not_test。

  5. not_test: 可以是 comparison 或 "not" not_test。

    not_test               ::=  comparison | "not" not_test

    9 不含 not,所以它被解析为 comparison。

  6. comparison: 可以是 or_expr (comp_operator or_expr)*。

    comparison             ::=  or_expr (comp_operator or_expr)*

    9 不含比较运算符,所以它被解析为 or_expr。

  7. or_expr: 可以是 xor_expr 或 or_expr "|" xor_expr。

    or_expr                ::=  xor_expr | or_expr "|" xor_expr

    9 不含位运算符 |,所以它被解析为 xor_expr。

  8. xor_expr: 可以是 and_expr 或 xor_expr "^" and_expr。

    xor_expr               ::=  and_expr | xor_expr "^" and_expr

    9 不含位运算符 ^,所以它被解析为 and_expr。

  9. and_expr: 可以是 shift_expr 或 and_expr "&" shift_expr。

    and_expr               ::=  shift_expr | and_expr "&" shift_expr

    9 不含位运算符 &,所以它被解析为 shift_expr。

  10. shift_expr: 可以是 a_expr 或 shift_expr (">") a_expr。

    shift_expr             ::=  a_expr | shift_expr ("<<" | ">>") a_expr

    9 不含移位运算符 >,所以它被解析为 a_expr。

  11. a_expr (additive expression): 可以是 m_expr 或 a_expr "+" m_expr 或 a_expr "-" m_expr。

    a_expr                 ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_expr

    9 不含加减运算符,所以它被解析为 m_expr。

  12. m_expr (multiplicative expression): 可以是 u_expr 或 m_expr "*" u_expr 等。

    m_expr                 ::=  u_expr | m_expr "*" u_expr | m_expr "@" m_expr |
                                  m_expr "//" u_expr | m_expr "/" u_expr |
                                  m_expr "%" u_expr

    9 不含乘、除、取模、矩阵乘法等运算符,所以它被解析为 u_expr。

  13. u_expr (unary expression): 可以是 power 或 "-" u_expr 等。

    u_expr                 ::=  power | "-" u_expr | "+" u_expr | "~" u_expr

    9 不含一元运算符(如 -、+、~),所以它被解析为 power。

  14. power: 可以是 (await_expr | primary) ["**" u_expr]。

    power                  ::=  (await_expr | primary) ["**" u_expr]

    9 不含 await 或 ** 运算符,所以它被解析为 primary。

  15. primary: 可以是 atom 或 attributeref 等。

    primary                ::=  atom | attributeref | subscription | slicing | call

    9 不是属性引用、订阅、切片或函数调用,所以它被解析为 atom。

  16. atom: 可以是 identifier、literal 或 enclosure。

    atom                   ::=  identifier | literal | enclosure

    9 既不是标识符也不是括号等,所以它被解析为 literal。

  17. literal: 可以是 stringliteral、bytesliteral、integer、floatnumber 或 imagnumber。

    literal                ::=  stringliteral | bytesliteral
                                  | integer | floatnumber | imagnumber

    9 显然是一个 integer。

  18. integer: 可以是 decinteger、bininteger、octinteger 或 hexinteger。

    integer                ::=  decinteger | bininteger | octinteger | hexinteger

    9 是一个十进制整数,最终被解析为 decinteger。

至此,我们成功地将数字9追溯到了其最基本的语法单元:decinteger,它完全符合Python的BNF语法规则。

关键洞察:可选语法元素的重要性

在上述解析路径中,一个非常重要的设计原则是:从conditional_expression到power的每个语法元素,其“特征性”的运算符或关键字往往是可选的。例如:

  • conditional_expression 中的 if ... else ... 部分是可选的。
  • or_test 中的 or 关键字是可选的。
  • power 中的 ** 运算符是可选的。

这意味着,即使一个表达式不包含任何特定的运算符(如if、or、+、*、**等),它仍然可以被解析为这些更高级别的语法元素。例如,2**16 是一个 power,但 2 本身也符合 power 的定义。正是这种设计,使得一个简单的数字字面量能够通过层层递归,向上匹配到 expression,并最终符合 starred_expression 的要求。

总结与实践意义

通过对Python赋值语句BNF的深入分析,我们理解了即使是最简单的a = 9形式,其右侧的数字9也严格遵循了语言的语法规则。这个过程揭示了:

  1. 递归性:BNF定义是高度递归的,允许复杂的表达式由简单的元素组合而成。
  2. 可选性:许多语法规则中的运算符或关键字是可选的,这使得一个基本元素(如字面量)能够向上匹配到更广泛的表达式类型。
  3. 层次结构:表达式的解析遵循一个明确的优先级和结构层次,从高层(如条件表达式)逐步细化到低层(如字面量)。

理解这些语法规则对于深入掌握Python语言的内部机制、进行代码解析、开发静态分析工具或理解编译器/解释器的工作原理都至关重要。它不仅解答了“9如何符合starred_expression”的疑问,更提供了一个窥探编程语言底层设计的窗口。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

713

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

625

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

738

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1235

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

574

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

696

2023.08.11

excel制作动态图表教程
excel制作动态图表教程

本专题整合了excel制作动态图表相关教程,阅读专题下面的文章了解更多详细教程。

30

2025.12.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 2.6万人学习

SciPy 教程
SciPy 教程

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号