a toy python interpreter
从上到下逐行执行。
ASCII 编码,区分大小写。中文字符是未定义的。
None True False def return break continue if elif else while or and not
关键字不可作为变量名或函数名。
空格、制表符在源文件中可以区分词素 (Token),同时在一行的开头可以表示缩进。
换行符表示新的语句的开始。
从 #
开始到本行结束的内容都会被作为注释。
标识符的第一个字符必须是英文字母,第二个字符开始可以是英文字母、数字或者下划线。
标识符区分大小写。长度超过
True
为真,False
为假。
整数常量以十进制表示。整数常量不设负数,负数可以由正数取负号得到。
整数的范围是没有限制的,这意味着你必须实现高精度整数。
首位为
字符串常量是由双引号或单引号括起来的字符串。
可以由两个字符串拼接而形成新的字符串常量。如 "123""456"
相当于 "123456"
。
字符串中的所有字符必须是可示字符 (printable character) 或空格中的一种。
None
用来表示变量没有指向任何值。
+ - * / // %
在字符串意义下 +
表示拼接,* a
表示拼接
/
是浮点除,//
是整除,%
是模运算。
运算的隐式类型转换参考 c++ 语法。当整除与模涉及到浮点数,此行为是未定义的行为。
整除(无论正负)可以看成浮点除之后向下取整(当然这不是正确写法,因为这样会造成有效数字丢失)
模运算无论正负定义为: a%b=a-(a//b)*b
。
< > <= >= == !=
连续比较:若出现 1<2>3
这样连续的关系运算符,将它拆成相邻的比较并用 and
连接,但每个值只计算一遍。如 a()<b()<c()
,相当于判断 a()<b() and b()<c()
但是 a(),b(),c()
只调用一遍。
and or not
与标准 python 语法不同,这里只返回布尔类型。
请注意逻辑运算的短路。
=
给一个变量赋值的意义是将这个变量指向右值,右值不管类型。
对于一个之前未定义的变量,赋值运算会先定义变量。
与标准 python 不同,全局变量的生效范围是全部范围 (不用 global 关键字即可访问)。
局部变量的生效范围是在当前语句块(被缩进和取消缩进包起来的部分),具体局部变量和全局变量划分规则和 c++ 一样。
如 a=1,a=”123”,a=1.1
这三条语句依次执行,再输出 a
,结果是 1.1
。
可以连等,如 a=b="123"
意思是 b="123",a=b
这两条语句依次执行。
可以给多变量赋值,如 a,b=1,2
意思是 a=1,b=2
依次执行。
+= -= *= /= //= %=
对字符串而言 +=
就是往后加字符,*=
就是把字符串复制多遍加起来,剩下两个符号对字符串无定义。
圆括号除了用在表达式里,可以用来调用函数,定义函数。
从低到高依次为
=
or
and
not
< > <= >= == !=
+ -
* / // %
()
bool
:只有 True
和 False
。
int
:高精度整数。
float
: 与 c++ 中的 double
一致。
str
: 字符串,immutable。
var_1 = (var_2 = ...) = value
语法规则参见赋值运算符。
var += value
或其他增量赋值
运算时如果两个运算数类型不一致,按照 c++ 规则执行自动类型转换。
if expression_1:
# code block
elif expression_2:
# code block
else expression_3:
# code block
elif
相当于 else if
,else
可以没有。
while expression:
# code block
break
return
continue
def func(parameters):
# code block
参数列表如 a,b,c
,变量名之间用逗号分隔,可以为空。
有些变量可以有默认值,但是都必须出现在无默认值的变量后面。
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)
。
print
:输出,可以有任意个参数,逐个输出,中间用空格分隔。输出后换行。输出 float
保留 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
。
转型类函数都只有一个参数。
数据保证递归层数不超过
-
Q:需不需要实现函数内定义函数的功能?
A:不需要。定义函数只能在全局最外层,在其它语句块内部均为未定义行为,不作要求。
本次作业要求用 OOP 实现,若不按照要求会在 code review 扣除一定分数。
作业按数据总的通过比例给分。助教会下发部分数据在作业仓库中,还有另一部分数据不会提供。
这意味着你需要自己手写测试数据给自己测试,如果你对自己造的数据是否满足要求有疑问,请及时向助教询问。
如果有实现要求之外的功能或者语法(如报错、容器、自定义类等),可酌情加分,最多不超过本作业的总分。
建议使用 antlr4 框架完成。助教组已经提供了现成的语法文件。
如果你想挑战自己,可以自己写 parser 或者自己重写语法文件。
如果有不懂的文法规则,参考 python3.g4
,以上面的规则为准。
如果有其他问题可以及时联系助教。