- 人工智能
- AI 技能
- 文档
- 开发工具
【免费下载链接】DocAgent
VarPattern 是仓颉(Cangjie)标准库std.ast中表示"绑定模式"的语法树节点,对应模式匹配中把匹配结果绑定到标识符的语法结构,例如for (i in 1..10)中的i。本文基于 std.ast 包 的官方类文档与源码级声明,完整讲解 VarPattern 的类定义、两个构造函数、identifier成员属性的读写规则,并结合 VarDecl、ForInExpr、MatchCase 等节点说明它的实际挂载位置,最后给出基于parsePattern解析与Visitor遍历的实战示例。读完本文,你将能识别并操作仓颉 AST 中任意一处"变量绑定模式"节点。
VarPattern 是什么:绑定模式节点
在仓颉的模式匹配体系中,模式(Pattern)用于描述"待匹配的数据应满足的结构",而绑定模式(binding pattern)是最基础的一类:它用一个合法的标识符将匹配到的值绑定到该名字上,后续代码可以直接引用这个名字。
按照 ast_package_classes.md 中的类说明,VarPattern 表示绑定模式节点,使用一个合法的标识符表示,官方给出的典型例子是:
for (i in 1..10)其中i就是循环迭代表达式中被绑定到当前元素的标识符,对应 AST 中一个VarPattern节点。
绑定模式出现的位置非常广泛:for-in循环的迭代表达式、match分支、let解构、变量声明等凡是"按模式取名字"的场景都可能出现它的身影,因此理解 VarPattern 是使用std.ast做源码解析、宏处理和代码分析的基础。
类声明与继承关系
在 ast_package_classes.md 中,VarPattern 的完整类声明为:
public class VarPattern <: Pattern { public init() public init(identifier: Token) }关键信息如下:
- 父类型:Pattern。
Pattern是public open class Pattern <: Node,即所有模式匹配节点的父类,它又继承自 Node(所有仓颉语法树节点的父类)。因此 VarPattern 天然具备 Node 的通用能力(如dump()、traverse(visitor)等)。 - 可构造性:与某些只能由解析器生成的节点不同,VarPattern 是
public类且提供了公开构造函数,开发者既可以"读"(从解析结果中取出),也可以"写"(手工构造后插入 AST)。
在std.ast的模式节点家族中,与 VarPattern 同属 Pattern 子类的还包括:ConstPattern(常量模式)、VarOrEnumPattern(标识符为Enum构造器的模式)、WildcardPattern(通配符_)、TuplePattern(元组模式)、TypePattern(类型模式)、EnumPattern(enum 模式)与 ExceptTypePattern(异常模式)等。后面会专门辨析它们之间的区分。
构造函数:两种创建方式
VarPattern 提供两个重载的构造函数,参见 ast_package_classes.md 的构造函数说明:
| 原型 | 说明 |
|---|---|
init() | 构造一个默认的 VarPattern 对象。 |
init(identifier: Token) | 根据标识符构造一个 VarPattern 对象。 |
init():默认构造
public init()创建一个"空壳"的绑定模式节点:此时节点内没有绑定任何标识符,需要后续通过identifier属性(见下一节)赋值后才能成为一个语义完整的模式节点。这种"先构造、后填充"的方式通常用于程序化构建 AST(例如宏展开时动态生成绑定)。
init(identifier: Token):根据标识符构造
public init(identifier: Token)直接传入一个表示绑定名的词法单元来构造节点。参数说明(摘自类文档):
identifier: Token—— 将要构造为 VarPattern 的词法单元,即绑定标识符对应的 Token。
需要特别注意的是该构造函数可能抛出异常(见 ASTException 类说明):
- ASTException—— 当输入的词法单元无法构造为 VarPattern 节点时抛出。
也就是说,并非任意Token都能成为合法的绑定模式:如果传入的 Token 不是合法的标识符词法单元(例如传入操作符或关键字),解析构造逻辑会判定无法构成 VarPattern 并抛出ASTException。因此在实际编码中,应当优先使用TokenKind.IDENTIFIER类型的词法单元来构造。
成员属性 identifier:读写绑定标识符
VarPattern 对外暴露的唯一成员属性是identifier,声明如下(见 ast_package_classes.md 的属性说明):
public mut prop identifier: Token语义:获取或设置 VarPattern 节点中标识符的词法单元。
由于是mut prop(可变属性),它同时支持读取和写入:
// 读取绑定名 let name = varPattern.identifier // 改写绑定名 varPattern.identifier = Token(IDENTIFIER, "newName")属性类型为 Token,即词法单元结构体。Token 是构成仓颉源码的最小单元,包含以下关键成员(详见 Token_struct.md):
| 成员 | 类型 | 含义 |
|---|---|---|
kind | TokenKind | 词法单元的类型(关键字、标识符、运算符、常量值等)。 |
pos | Position | 词法单元在源码中的位置信息(文件 ID、行号、列号)。 |
value | String | 词法单元的字面量值。 |
delimiterNum | UInt16 | 多行字符串的#符号个数(默认 1)。 |
因此对于一个解析自真实源码的 VarPattern,identifier.kind通常为IDENTIFIER、identifier.value就是绑定名本身(如i)、identifier.pos记录了该名字在源文件中的行列位置——这对做源码级诊断和定位非常有用。
VarPattern 在 AST 中的典型挂载场景
VarPattern 作为 Pattern 的子类,会被"持有模式"的各种上层节点引用。从std.ast的类定义可以确认以下几个典型的挂载位置:
变量定义节点 VarDecl
VarDecl 表示变量定义节点,其成员属性中包含:
public mut prop pattern: Pattern即变量声明的模式部分。例如解析var a : Int64时,pattern就是绑定标识符a的 VarPattern 节点。在 parse.md 示例的 dump 输出 中可以看到,var a: Int32被解析为 VarDecl 后,其identifier(值为a、kind: IDENTIFIER)即对应这个绑定。
for-in 循环节点 ForInExpr
ForInExpr 表示for-in表达式,其成员属性:
public mut prop pattern: Pattern对应官方文档中 VarPattern 的典型例子for (i in 1..10)里的i。循环体每轮迭代都会把当前元素绑定到该模式命名的变量上。
let 解构节点 LetPatternExpr
LetPatternExpr 表示let声明的解构匹配节点:
public mut prop pattern: Pattern对应let关键字之后的 pattern,当解构的是单个标识符(如let x <- foo())时,该 pattern 即为 VarPattern。
match 分支节点 MatchCase
MatchCase 表示match表达式中的一个case节点:
public mut prop patterns: ArrayList<Pattern>case后的 pattern 集合中,绑定模式就是 VarPattern。例如case i => ...会把匹配值绑定到i。此外 MatchExpr 通过matchCases持有多个 MatchCase,形成完整的模式匹配表达式。
与相近模式节点的辨析
std.ast中几个"单标识符形态"的模式节点容易混淆,从各自的类说明可以清晰区分:
| 节点 | 语义 | 典型形态 |
|---|---|---|
| VarPattern | 绑定模式:把匹配值绑定到一个合法标识符 | for (i in 1..10)中的i |
| VarOrEnumPattern | 标识符解析为Enum构造器时的模式 | case RED中的RED(RED 是枚举构造器) |
| ConstPattern | 常量模式:匹配字面量常量 | case 1 => 0中的1 |
| WildcardPattern | 通配符模式:匹配任意值但不绑定 | _ |
判断要点:模式的名字若会被"绑定复用",则是 VarPattern;若指向枚举构造器(按值比较是否命中),则是 VarOrEnumPattern;若是字面量常量,则是 ConstPattern;若用_忽略匹配值,则是 WildcardPattern。
实战:解析、遍历与构造 VarPattern
用 parsePattern 解析出 VarPattern
std.ast提供了解析函数parsePattern(Tokens)(见 ast_package_funcs.md),可将一组词法单元解析为 Pattern 节点。结合quote与类型转换(模式参考 parse.md 示例 的as ClassDecl写法),可以这样拿到 VarPattern:
import std.ast.* main() { let input: Tokens = quote(i) // 将源码片段转为词法单元 let pattern = parsePattern(input) // 解析出一个 Pattern 节点 var varPattern = match (pattern as VarPattern) { // 类型收敛到 VarPattern case Some(v) => v case None => throw Exception() } println("binding name is ${varPattern.identifier.value}") 0 }其中varPattern.identifier.value将输出绑定名(此处为i),identifier.pos则记录了它的源码位置。
通过 Visitor 遍历包含 VarPattern 的节点
在 traverse.md 示例 中,展示了继承 Visitor 并重写visit(varDecl: VarDecl)来扫描变量声明节点的做法。同理,若要收集某个作用域内所有绑定模式的名字,可以重写对模式相关节点的访问逻辑,通过varDecl.pattern(或forInExpr.pattern、matchCase.patterns)逐层下钻,判断其动态类型是否为 VarPattern,再读取identifier.value:
class BindingCollector <: Visitor { public var bindings = ArrayList<String>() override public func visit(varDecl: VarDecl) { // 从声明节点的 pattern 中取绑定名 if (varDecl.pattern is VarPattern) { let vp = varDecl.pattern as VarPattern bindings.add(vp.identifier.value) } return } }说明:以上基于 Visitor 与 VarDecl.pattern 的公开接口推导,具体遍历粒度以所用
std.ast版本的 Visitor 默认实现为准。
手工构造并修改绑定模式
宏展开或代码生成场景下,往往需要程序化创建绑定模式。两种构造方式结合identifier属性即可完成:
import std.ast.* main() { // 方式一:默认构造后写入标识符 let p1 = VarPattern() p1.identifier = Token(IDENTIFIER, "item") // 方式二:直接以标识符词法单元构造 let p2 = VarPattern(Token(IDENTIFIER, "item")) println("${p1.identifier.value} ${p2.identifier.value}") 0 }Token(IDENTIFIER, "item")使用了 Token 的构造函数init(kind: TokenKind, value: String),其中IDENTIFIER是 TokenKind 中表示标识符的枚举值(在 parse.md 的 dump 输出 中可见kind: IDENTIFIER的实例)。构造完成后,即可把该 VarPattern 挂到 VarDecl 的pattern或 ForInExpr 的pattern上,参与更大 AST 的组装。
异常与使用注意事项
围绕 VarPattern 的使用,需要留意以下几点(依据来自类文档与异常类定义):
- 构造失败会抛 ASTException:
init(identifier: Token)在输入的词法单元无法构成绑定模式时会抛出 ASTException,建议构造前确认 Token 的类型为IDENTIFIER。 - identifier 属性语义要求合法标识符:
identifier属性用于读写"标识符的词法单元",写入的值应当与绑定模式的语义一致(合法标识符),否则可能影响后续解析或宏展开的正确性。 - 解析失败场景:使用
parsePattern等解析函数时,若输入词法单元无法解析为合法模式,会抛出 ParseASTException(std.ast的解析异常类),该异常与 ASTException 同属std.ast的异常体系,捕获时可按需分别处理。 - 绑定模式不是"表达式":VarPattern 继承自 Pattern 而非 Expr,它只描述"名字绑定"这一结构,本身不参与求值,切勿在需要表达式的字段(如
VarDecl.expr)中直接挂入。
综上,VarPattern 是仓颉 AST 中连接"模式匹配语法"与"标识符绑定"的关键节点:读懂它,就能在for、match、let、变量声明等几乎所有涉及绑定的语法场景中,精确地解析、遍历和生成绑定名字,这是编写宏、静态分析器与代码生成工具的基础能力之一。建议进一步阅读 std.ast 包概览 了解完整节点体系,并结合 parse.md、operate.md、traverse.md 三个样例加深对 AST 解析与操作的整体理解。
- 人工智能
- AI 技能
- 文档
- 开发工具
【免费下载链接】DocAgent
相关推荐
仓颉 std.ast 的 ThrowExpr:throw 表达式语法树节点详解
仓颉 std.ast 的 ThrowExpr:throw 表达式语法树节点详解 ThrowExpr 是仓颉 std.ast 包中用于表示 throw 表达式节点
人工智能AI 技能文档开发工具仓颉 std.ast 语法树节点详解:VarDecl 变量定义节点的构造、属性访问与实战操作
仓颉 std.ast 语法树节点详解:VarDecl 变量定义节点的构造、属性访问与实战操作 本文以仓颉标准库 std.ast 包中的 VarDecl 类为核心
人工智能AI 技能文档开发工具仓颉 std.ast 语法树节点解析:ParenExpr 括号表达式节点的构造、读写与实战
仓颉 std.ast 语法树节点解析:ParenExpr 括号表达式节点的构造、读写与实战 ParenExpr 是仓颉 std.ast 包中表示括号表达式(即使
人工智能AI 技能文档开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考