244 lines
7.5 KiB
Markdown
244 lines
7.5 KiB
Markdown
## 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::striing`,`>=`, `==`等同理
|
||
- 除法
|
||
- `/` 表示浮点除,即计算结果为浮点数
|
||
- `//` 表示整除,即计算结果为整数。注意无论正负皆**向下取整**,例如 `-5 // 3 = -2`
|
||
- `%` 表示模运算,无论模数的正负,皆定义为:`a % b = a - (a // b) * b`
|
||
- 连续比较
|
||
- 存在 `1<2>3` 这样连续的关系运算符,处理方法是将其拆为相邻的比较并用 `and` 连接但**每个值最多只计算一次**
|
||
- 如 `a()<b()<c()`,等价于先翻译成 `a()<b() and b()<c()` 再进行计算, `a(),b(),c()` 最多只调用一次(因为短路运算符)
|
||
- 逻辑运算符
|
||
- `and` 等价于 C++ 中的 `&&`,`or` 等价于 C++ 中的 `||`, `not` 等价于 C++ 中的 `!`
|
||
- `and` 和 `or` 为**短路**运算符
|
||
- **隐式转化**
|
||
- 运算时如果两个运算数类型不一致,需转化成相同类型之后再进行运算
|
||
- 具体转化规则参考 C++
|
||
|
||
不包含在特殊行为和 C++ 标准中的行为均为**未定义**行为。
|
||
|
||
#### 8.3. 赋值表达式
|
||
|
||
- 给一个变量赋值的意义是将这个变量指向右值,右值不管类型
|
||
- 如 `a=1,a=”123”,a=1.1` 这三条语句依次执行,再输出 `a`,结果是 `1.1`,允许变量遮蔽
|
||
- 可以给多变量赋值,如 `a,b=1,2` 意思是 `a=1,b=2` 依次执行,此处或与标准 Python **不同**
|
||
- 增量赋值即为普通算术运算的简化表达,具体行为参考 C++
|
||
|
||
#### 8.4. 运算符优先级
|
||
|
||
从低到高依次为(其中处在相同行的运算符优先级相同)
|
||
|
||
```python
|
||
=
|
||
or
|
||
and
|
||
not
|
||
< > <= >= == !=
|
||
+ -
|
||
* / // %
|
||
()
|
||
```
|
||
|
||
### 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即可访问,因此,局部变量覆盖全局变量的唯一方式是通过函数参数列表覆盖。
|