菜单

语义分析

相关源文件

语义分析是Sway编译器中的关键阶段,它接收已解析的语法树,并执行类型检查、符号解析和各种有效性检查,以确保程序在语义上是正确的。本页将解释Sway编译器在解析代码后、将其转换为中间表示(IR)之前,如何分析代码的含义。有关IR生成的信息,请参阅IR生成

语义分析概述

Sway中的语义分析负责:

  1. 将声明收集并组织到命名空间层级结构中
  2. 检查表达式和语句的类型正确性
  3. 将符号引用解析为其声明
  4. 验证特性实现
  5. 执行控制流分析
  6. 检测死代码和不可达语句

语义分析阶段围绕两个主要遍次构建:

  1. 符号收集 - 收集声明并构建符号表
  2. 类型检查 - 验证类型正确性并推断类型

来源

语义分析的关键组件

Sway中的语义分析围绕几个关键组件展开,它们协同工作以验证程序:

TypeCheckContext

语义分析的核心是TypeCheckContext结构体,它在类型检查期间维护状态。它封装了:

  • 命名空间:用于符号解析的当前命名空间上下文
  • 引擎:对类型引擎和声明引擎的引用
  • 类型注解:用于推断的预期类型
  • 自身类型:在检查特性或实现块时,self的类型
  • ABI模式:我们是否正在检查ABI实现

TypeCheckContext提供了以下方法:

  • 进入和退出词法作用域
  • 解析类型和符号
  • 管理类型注解和统一
  • 处理特性实现

来源

命名空间系统

命名空间系统组织声明并管理符号解析:

  • 命名空间(Namespace):管理包和模块的顶层容器
  • 模块(Module):表示一个带有自身作用域和子模块的Sway模块
  • 词法作用域(LexicalScope):表示一个词法作用域,其中定义了符号
  • 特性映射(TraitMap):将类型映射到其特性实现

来源

类型系统集成

语义分析与类型系统密切互动:

  • TypeEngine:创建和管理类型信息
  • TypeId:类型的唯一标识符
  • TypeInfo:实际的类型信息(枚举、结构体、原始类型等)
  • 统一(Unification):确定类型是否兼容的过程

来源

符号收集

符号收集是语义分析的第一遍,它在命名空间层级结构中收集和组织声明。

在符号收集过程中:

  1. 每个AST节点都被访问,其声明被收集
  2. 对于函数、结构体、枚举等,它们的名称被添加到符号表中
  3. 为块和声明创建新的词法作用域
  4. 处理use语句以从其他模块导入符号

这在TyAstNode::collect方法中实现,该方法根据节点类型分派给特定的收集器。

来源

类型检查

类型检查遍次验证类型正确性并执行类型推断。

类型检查在TyAstNode::type_check方法中实现,该方法:

  1. 根据节点类型分派给特定的检查器
  2. 对于表达式,推断并检查类型
  3. 对于声明,验证其内部一致性
  4. 执行统一以确保类型兼容性
  5. 当类型不匹配时报告错误

类型检查器递归检查表达式及其子表达式,使用类型注解来指导推断。

来源

表达式类型检查

类型检查表达式是语义分析中最复杂的方面之一。对于每种表达式类型:

  1. 变量:在命名空间中查找变量并获取其类型
  2. 函数调用:解析函数,检查参数类型,推断泛型参数
  3. 方法调用:查找合适的方法实现,检查接收者和参数
  4. 结构体实例化:验证字段类型与结构体声明匹配
  5. 控制流:检查条件是否为布尔类型,确保分支具有兼容的类型

TyExpression::type_check方法处理此过程并返回一个类型化表达式。

来源

声明类型检查

声明类型检查确保声明的内部一致性:

  1. 函数:检查参数类型、返回类型和函数体
  2. 结构体/枚举:验证字段类型和变体
  3. 特性声明:检查特性方法和关联类型
  4. 实现:验证所有特性要求均已满足

来源

类型解析和统一

语义分析的一个关键方面是类型解析和统一:

类型解析包括:

  1. 将类型标识符转换为实际类型
  2. 解析泛型类型参数
  3. 应用类型约束
  4. 处理类型别名和关联类型

类型统一是确定两种类型是否兼容,如果兼容,哪种类型更具体的过程。

来源

特性解析和实现

特性解析和实现检查是语义分析的复杂部分:

特性实现过程:

  1. 解析特性声明和实现类型
  2. 检查所有必需的方法、关联类型和常量是否已实现
  3. 验证签名和实现是否符合要求
  4. TraitMap中注册实现以进行方法解析

来源

附加语义检查

除了类型检查,Sway还执行几项高级语义分析:

死代码分析

死代码分析识别永远不会被执行的代码:

  1. 构建控制流图
  2. 查找从入口点无法到达的节点
  3. 报告不可达代码的警告

来源

返回路径分析

返回路径分析确保函数在所有代码路径上都返回值:

  1. 分析所有可能的执行路径
  2. 验证每条路径要么返回值,要么永不终止
  3. 报告可能不返回值的路径的错误

来源

错误处理和恢复

语义分析包括强大的错误处理:

  1. 针对不同语义错误的特定错误类型
  2. 错误恢复以在错误发生时继续分析
  3. 提供有用的、带有上下文和建议的错误消息
  4. 在停止编译之前收集多个错误

当检测到类型错误时,编译器:

  1. 创建一个包含预期类型和实际类型信息的错误
  2. 包含相关的源代码位置
  3. 添加解释问题的帮助消息
  4. 在可能的情况下继续分析以查找更多错误

来源

结论

Sway中的语义分析是一个复杂的处理过程,它确保程序在代码生成之前格式正确且类型正确。通过结合符号解析、类型检查和高级语义分析,Sway编译器可以在编译期间捕获各种错误,并提供有用的消息来指导开发人员解决问题。

该系统设计为可扩展的,允许添加新的语言特性和语义检查,同时保持现有分析的健壮性。