这段有没有语义错误
按模型,has_err([("set","x",["1"]), ("print",None,["x"])]) 交回什么?
贯穿本节的小语言(判题机没 gcc,这是它的确定模型,见 spine.py):每行一条语句——set 名 = 表达式 或 print 表达式;表达式是空格分隔的 token,从左到右求值(无优先级),数字 token 当值、名字到环境里查(没有当 0)。
declared 收集 set 定义过的名字,used 收集表达式里用到的名字,undefined 交回「用了却没定义」的名字,ok=没有未定义变量。
line_no(prog, 名) 找变量第一次出现的行号,fmt(行, 说明) 拼一条报错,has_err=有没有语义错误,err_count=未定义变量个数。
def kind(tok):
if tok.lstrip("-").isdigit():
return "num"
if tok in ("+", "-", "*", "="):
return "op"
return "name"
def declared(prog):
return [n[1] for n in prog if n[0] == "set"]
def undefined(prog):
d = set(declared(prog))
us = [t for n in prog for t in n[2] if kind(t) == "name"]
return sorted(set(u for u in us if u not in d))
def line_no(prog, name):
"""第一处用到某变量的语句行号(从 1 数);没有交回 0。"""
for i, n in enumerate(prog, 1):
if name in n[2]:
return i
return 0
def fmt(line, msg):
"""拼一条友好报错:第 L 行: msg。"""
return "第" + str(line) + "行:" + msg
def has_err(prog):
"""有没有语义错误(未定义变量)。"""
return undefined(prog) != []
def err_count(prog):
"""一共几个未定义变量。"""
return len(undefined(prog))
print(has_err([("set", "x", ["1"]), ("print", None, ["x"])]))
全部评论