← 返回目录

第五章:作用域与符号表

用 Scope 和 SymbolInfo 处理声明、查找、重复声明与未定义变量诊断。

1. 作用域链

每个块都可以创建 Scope,define() 在当前作用域记录 SymbolInfo,resolve() 沿父链查找名称。重复声明应该在 define 阶段报错,未定义变量应该在 resolve 失败时形成诊断。

type SymbolInfo = { name: string; type: ValueType; declaredAt: Position };

class Scope {
  private symbols = new Map<string, SymbolInfo>();
  constructor(private parent?: Scope) {}

  define(symbol: SymbolInfo): void {
    if (this.symbols.has(symbol.name)) throw new Error("重复声明");
    this.symbols.set(symbol.name, symbol);
  }

  resolve(name: string): SymbolInfo | undefined {
    return this.symbols.get(name) ?? this.parent?.resolve(name);
  }
}

2. 块级名称

MiniLang 的块级作用域让局部变量只在花括号内可见。示例 { let local: number = 1; print(local); } 中 local 可以解析成功,但离开块以后再次访问就会触发未定义变量。

{ let local: number = 1; print(local); }
上一章:AST 与语义模型 返回目录 下一章:类型检查