跑之前一次查全
(每道题开头都有同一段:表达式用嵌套元组表示——("num",5) 是整数、("str","x") 字符串、("bool",True) 布尔、("var","x") 变量、("add",e1,e2) 相加、("eq",e1,e2) 相等、("if",c,e1,e2) 条件。type_of(e, env) 推它的类型,不合法交回 "ERR"。)
(这一节还有:check_prog(stmts) 把 [(变量名, 表达式)] 按顺序推类型、记进环境,某条 ERR 计一个错,交回 (错误数, 记住的变量数);first_error 交回第一条出错的变量名。)
一段程序:a=1、b=a+"x"(错)、c=3。静态检查一次查全,问错误数和记住的变量数:
def type_of(e, env):
"""给表达式推类型:num→int、str→str、bool→bool、var 查 env、运算查操作数。不合法交回 "ERR"。"""
k = e[0]
if k == "num":
return "int"
if k == "str":
return "str"
if k == "bool":
return "bool"
if k == "var":
return env.get(e[1], "ERR")
if k == "add": # 同类型、且是 int 或 str 才能加
a = type_of(e[1], env)
b = type_of(e[2], env)
if a == b and a in ("int", "str"):
return a
return "ERR"
if k == "eq": # 同类型才能比,结果是 bool
a = type_of(e[1], env)
b = type_of(e[2], env)
if a != "ERR" and a == b:
return "bool"
return "ERR"
if k == "if": # 条件必 bool,两分支同类型
c = type_of(e[1], env)
a = type_of(e[2], env)
b = type_of(e[3], env)
if c == "bool" and a == b and a != "ERR":
return a
return "ERR"
return "ERR"
def check_prog(stmts):
"""stmts: [(变量名, 表达式)],按顺序推类型记进环境;某条 ERR 就计一个错、不记这个变量。交回 (错误数, 记住的变量数)。"""
env = {}
errs = 0
for name, expr in stmts:
t = type_of(expr, env)
if t == "ERR":
errs += 1
else:
env[name] = t
return errs, len(env)
def first_error(stmts):
"""交回第一条类型出错的变量名;全对交回空串。"""
env = {}
for name, expr in stmts:
t = type_of(expr, env)
if t == "ERR":
return name
env[name] = t
return ""
prog = [("a", ("num", 1)), ("b", ("add", ("var", "a"), ("str", "x"))), ("c", ("num", 3))]
e, v = check_prog(prog)
print(str(e) + "/" + str(v))
全部评论