整段源码跑出什么

👁️ 3 人浏览 💬 0 人评论 ❤️ 添加收藏

按模型,compile_run(["set x = 1 + 2", "print x * 10"]) 交回什么?

贯穿本节的小语言(判题机没 gcc,这是它的确定模型,见 spine.py):每行一条语句——set 名 = 表达式print 表达式;表达式是空格分隔的 token,从左到右求值(无优先级),数字 token 当值、名字到环境里查(没有当 0)。

parse 把一行变成 AST 元组:set("set", 名, 表达式tokens)print("print", None, 表达式tokens)prog 是这些元组的列表。

端到端:parse_all 逐行 parse,valid 查语义是否 OK,compile_run 从源码跑到输出(不合法交回 ["ERROR"]),result=最后一次 print 的值。

def parse(line):
    t = line.split()
    if t[0] == "set":
        return ("set", t[1], t[3:])
    return ("print", None, t[1:])


def val(tok, env):
    if tok.lstrip("-").isdigit():
        return int(tok)
    return env.get(tok, 0)


def eval_expr(tokens, env):
    acc = val(tokens[0], env)
    i = 1
    while i + 1 < len(tokens):
        op = tokens[i]
        rhs = val(tokens[i + 1], env)
        acc = acc + rhs if op == "+" else (acc - rhs if op == "-" else acc * rhs)
        i += 2
    return acc


def parse_all(lines):
    """把每行源码都 parse 成 AST。"""
    return [parse(l) for l in lines]


def n_stmts(lines):
    """源码一共几条语句(几行)。"""
    return len(lines)


def valid(lines):
    """整段源码语义 OK 吗:用到的变量都先 set 定义过。"""
    prog = parse_all(lines)
    d = set(n[1] for n in prog if n[0] == "set")
    for n in prog:
        for t in n[2]:
            if not t.lstrip("-").isdigit() and t not in ("+", "-", "*") and t not in d:
                return False
    return True


def compile_run(lines):
    """从源码到运行:不合法交回 ["ERROR"],否则交回 print 输出列表。"""
    if not valid(lines):
        return ["ERROR"]
    env = {}
    out = []
    for n in parse_all(lines):
        if n[0] == "set":
            env[n[1]] = eval_expr(n[2], env)
        else:
            out.append(eval_expr(n[2], env))
    return out


def result(lines):
    """端到端跑完,最后一次 print 的值。"""
    o = compile_run(lines)
    return o[-1] if o else None

print(compile_run(["set x = 1 + 2", "print x * 10"]))
提交你的答案
请登录后提交答案。
去登录
代码编辑器
Ctrl + Enter 运行
本次输入:
输出:

                        
👩‍🏫
AI
💬 题目评论

全部评论