## Specific Python ### I. 程序结构 按照控制流逐行执行。 ### II. 语法规则 #### 1. 字符集合 ASCII 编码,区分大小写,中文字符是**未定义**的,合法字符集如下: - **标识符**(包括变量标识符、函数标识符):26 个小写英语字母,26 个大写英语字母,数码 `0` 到 `9`,下划线 `_` - **标准运算符**:加号 `+`,减号 `-`,乘号 `*`,浮点除 `/`,整除`//`,取模 `%` - **关系运算符**:大于 `>`,小于 `<`,大于等于 `>=`,小于等于 `<=`,不等于 `!=`,等于 `==` - **增量运算符**:加法 `+=`,减法 `-=`,乘法 `*=`,浮点除 `/=`,整除 `//=`,取模`%=` - **赋值运算符**:赋值 `=` - **下标运算符**:取下标对象 `[]` - **优先级运算符**:括号 `()` - **分隔符**:逗号 `,` - **特殊符号**:空格 ` `,换行符 `\n`,制表符 `\t`,注释标识符 `#`,字符串标识符 `"` 或 `'`。 #### 2. 关键字 ```python None True False def return break continue if elif else while or and not ``` 关键字不可作为变量名或函数名。 #### 3. 空白字符 **空格**、**制表符**在源文件中可以区分词素 (Token),同时在一行的开头可以表示缩进。 **换行符**表示新的语句的开始。 缩进在 Python 用于识别代码块,相关问题将在 Parser 中使用 Antlr4 解决,无需考虑相关的实现。 #### 4. 注释 从 `#` 开始到本行结束的内容都会被作为注释。 #### 5. 标识符 标识符的第一个字符必须是英文字母,第二个字符开始可以是英文字母、数字或者下划线。 标识符区分大小写。长度超过 $64$ 个字符的标识符是**未定义**的。 #### 6. 常量 - 逻辑常量:`True` 为真,`False` 为假 - 整数常量: - 整数常量以十进制表示,非十进制的表示为**未定义**行为 - 整数常量不设负数,负数可以由正数取负号得到 - Python 中,整数的范围是没有限制的,此处同理,这意味着你必须实现高精度整数 - 首位为 $0$ 的整数常量是**未定义**的 - 浮点数常量: - 浮点数常量以十进制表示 - 浮点数常量不设负数,负数可以由正数取负号得到 - 拥有前导 $0$ 的浮点数为**未定义**的,如`0001.1` - 含有 e 的浮点数为**未定义**的,如 `1e5` - 以 . 开头的浮点数为**未定义**的,如 `.123` - 字符串常量 - 字符串常量是由双引号 `"` 或单引号 `'` 括起来的字符串 - 可以由两个字符串拼接而形成新的字符串常量。如 `"123""456"` 相当于 `"123456"` - 字符串中的所有字符必须是可示字符 (printable character) 或空格中的一种 - 空值常量:`None` 用来表示变量没有指向任何值 ### 7. 数据类型 - `bool`:只有 `True` 和 `False` - `int`:高精度整数 - `float`: 与 C++ 中的 `double` 一致 - `str`:字符串,**不可修改!** - 元组: 具体表现请参考 python (待完善) ### 8. 表达式 #### 8.1. 基础表达式 基础表达式包括单独出现的常量、变量、函数调用和数组访问。 #### 8.2. 算术表达式 合法的算术运算符包括:`+`, `-`, `*`, `/`, `//`, `%`,具体行为可以参照 C++,特殊行为有: - 字符串运算符 - `str + str` 表示字符串的拼接 - `str * int` 表示字符串的重复 - `str <= str` 表示字符串的比较,比较规则同 C++ `std::string`,`>=`, `==`等同理 - 除法 - `/` 表示浮点除,即计算结果为浮点数 - `//` 表示整除,即计算结果为整数。注意无论正负皆**向下取整**,例如 `-5 // 3 = -2` - `%` 表示模运算,无论模数的正负,皆定义为:`a % b = a - (a // b) * b` - 比较 - `==` 和 `!=` 会尝试将两边的值转化为相同类型后再进行比较,但并不会转化为 `str` 类型。无法转化时,比较结果为 `False`。 - 连续比较 - 存在 `1<2>3` 这样连续的关系运算符,处理方法是将其拆为相邻的比较并用 `and` 连接但**每个值最多只计算一次** - 如 `a() <= >= == != + - * / // % () ``` ### 9. 语句 #### 9.1. 变量定义/赋值语句 - 单变量赋值:`var = value` - 连续赋值:`var_1 = var_2 = ... = value` 参考[赋值表达式](####8.3. 赋值表达式)。 #### 9.2. 表达式语句 参考[表达式](###8. 表达式) #### 9.3. 条件语句 ```python if expression_1: # code block elif expression_2: # code block else expression_3: # code block ``` `elif` 相当于 `else if`,`else` 可以没有。 #### 9.4. 循环语句 ```python while expression: # code block ``` #### 9.5. 跳转语句 - 包括 `return`,`break`,和 `continue` - 具体行为参考 C++ ### 10. 函数 #### 10.1. 函数定义 ```python def func(parameters): # code block ``` - 参数列表如 `a, b, c`,变量名之间用逗号分隔,可以为空 - 有些变量可以有默认值,但是都必须出现在无默认值的变量后面 - 函数可以有返回值,也可以没有返回值,无需显示声明。返回值可以为多变量,如 `return a, b` #### 10.2. 函数调用 ```python func(parameters) ``` - 函数调用必须出现在该函数定义后。 - 参数有两种形式:keyword 和 positional - Keyword argument 比如 `foo(a=1,b=2)` 表示传入参数 `a` 的值为 `1`,`b` 的值 `2` - Positional argument 是指 `foo(1,2)` 这样按照出现顺序指代参数 - 若一个参数列表中同时有两种参数形式,那么 positional argument 必须出现在 keyword argument 之前。如 `foo(1,b=2)` - 数据保证递归层数不超过 $2000$ 层 ### 11. 内建函数 - `print`:输出,可以有任意个参数,逐个输出,中间用空格分隔。输出后换行。输出 `float` 保留 $6$ 位小数。输出字符串不要输出前后面的引号。如 `print("123",1.0)` 请输出 `123 1.000000`。 - `int`:将 `float` 或 `bool` 或 `str` 转成 `int`。 - `float`: 将 `int` 或 `bool` 或 `str` 转成 `float`。 - `str`: 将 `int` 或 `float` 或 `bool` 转成 `str`。 - `bool`: 将 `int` 或 `float` 或 `str` 转成 `bool`。对于 `str`,如果是 `""` 则为 `False`,否则为 `True`。 - 转型类函数都只有一个参数。 ### 12. 作用域 作用域相关规则: - **与标准 Python 不同,全局变量的生效范围是全部范围**(不用 global 关键字即可访问) - **只有函数的调用会产生新的作用域**,作用域的产生请参考 Python - 没有代码块级作用域,变量注销只发生在函数级作用域退出时 - 全局作用域无需global即可访问,因此,局部变量覆盖全局变量的唯一方式是通过函数参数列表覆盖。