资讯动态

仓颉 AST 宏调用参数节点 MacroExpandParam:类结构、属性详解与实战解析

发布时间:2026/10/15 15:17:45 来源:尧图企业网站定制
人工智能AI 技能文档开发工具【免费下载链接】DocAgent项目地址https://gitcode.com/Cangjie-SIG/DocAgent点击查看免费下载导读MacroExpandParam是仓颉std.ast包中用于表示函数参数位置上宏调用的语法树节点典型形态是func foo (M a: Int64)中的M a: Int64。本文以该类的官方 API 文档为主线结合仓库内ast_package_classes.md的完整类定义梳理其继承关系、构造函数与全部成员属性并通过与MacroExpandDecl、MacroExpandExpr等兄弟节点的对比帮助你掌握如何在宏展开、AST 遍历与节点改写场景中正确读取和设置宏调用参数节点的各个组成部分。类定位参数位置上的宏调用MacroExpandParam定义于 ast_package_classes.md其完整声明为public class MacroExpandParam : FuncParam { public init() }从源码结构看MacroExpandParam的直接父类是FuncParam函数参数节点而FuncParam又继承自Decl声明节点Decl继承自Node。因此它既是函数参数又是声明具备完整的 AST 节点能力。它对应的是宏出现在函数形参位置的场景func foo (M a: Int64) { ... }其中M a: Int64整体被解析为一个MacroExpandParam节点宏调用M负责在编译期改写该参数a: Int64则是被宏处理的输入内容。注意官方文档中MacroExpandDecl、MacroExpandExpr、MacroExpandParam三者的功能描述均为表示宏调用节点它们分别对应宏出现在声明位置如M class A {}、表达式位置如M (a is Int64)与参数位置如M a: Int64三种形态。构造函数MacroExpandParam只提供一个构造函数名称原型说明init()构造一个默认的MacroExpandParam对象。与MacroDecl、MacroExpandDecl、MacroExpandExpr均提供init(Tokens)重载不同MacroExpandParam不支持直接由词法单元集合Tokens构造。这是因为宏调用参数节点的输入结构标识符 括号 输入 Tokens 声明节点需要通过解析流程整体生成构造后通常借助各mut prop属性逐步填充。创建默认节点后各属性初始值遵循相应类型的默认状态例如Token默认kind为ILLEGAL、value为空字符串。成员属性详解MacroExpandParam共定义 8 个成员属性全部为可读写的public mut prop用于获取或设置宏调用参数节点的各个组成部分。完整标识符fullIdentifierpublic mut prop fullIdentifier: Token获取或设置宏调用节点的完整标识符类型为 Token。完整意味着该标识符可能携带模块/包限定信息例如mymod.M a: Int64中的mymod.M整体对应一个fullIdentifier。这一点与表达式位置的MacroExpandExpr.identifier属性有所区别后者仅保存单个标识符详见 MacroExpandExpr。圆括号lParen 与 rParenpublic mut prop lParen: Token public mut prop rParen: Token获取或设置宏调用的(与)。当参数位置的宏调用带有显式括号参数如M(...) a: Int64时这两个属性保存括号词法单元。设置时若传入的Token不是(或)将抛出 ASTException。方括号lSquare 与 rSquarepublic mut prop lSquare: Token public mut prop rSquare: Token获取或设置属性宏调用的[与]。仓颉宏支持属性式调用形态如M[attr1, attr2]此时属性参数由方括号包裹。与圆括号类似设置错误的词法单元同样会抛出ASTException。宏调用输入macroInputspublic mut prop macroInputs: Tokens获取或设置宏调用的输入类型为 Tokens。在M a: Int64场景中macroInputs保存被宏处理的输入词法单元序列。Tokens是Token序列的封装类型支持size、get(index)、iterator()、append、toString()等操作完整接口见 Tokens。属性宏输入macroAttrspublic mut prop macroAttrs: Tokens获取或设置属性宏调用的输入同样为Tokens类型。当宏以属性形式调用M[...]时方括号内的内容存入macroAttrs而当宏以普通形式调用时输入存入macroInputs。二者共同覆盖了两种宏调用语法形态的输入承载。声明节点macroInputDeclpublic mut prop macroInputDecl: Decl获取或设置MacroExpandParam中的声明节点类型为 Decl。宏展开后输入内容会被解析为具体的声明如变量声明a: Int64对应的VarDecl保存在该属性中供宏实现读取或改写。若节点中没有声明节点访问该属性将抛出ASTException。属性速查表属性原型说明类型fullIdentifierpublic mut prop fullIdentifier: Token宏调用节点的完整标识符TokenlParenpublic mut prop lParen: Token宏调用的(TokenlSquarepublic mut prop lSquare: Token属性宏调用的[TokenmacroAttrspublic mut prop macroAttrs: Tokens属性宏调用的输入TokensmacroInputDeclpublic mut prop macroInputDecl: Decl宏调用中的声明节点DeclmacroInputspublic mut prop macroInputs: Tokens宏调用的输入TokensrParenpublic mut prop rParen: Token宏调用的)TokenrSquarepublic mut prop rSquare: Token属性宏调用的]Token继承自 FuncParam 的成员由于MacroExpandParam : FuncParam它还继承了函数参数节点的通用能力详见 FuncParam包括assign: Token具有默认值的函数参数中的colon: Token形参中的:expr: Expr具有默认值的参数的初始化表达式not: Token命名形参中的!paramType: TypeNode参数的类型isMemberParam(): Bool判断该参数是否为主构造函数中的参数。这意味着一方面可以利用参数位置宏对参数做语法级改写另一方面被宏处理的参数本身仍然保留普通函数参数的语义信息宏实现可以在展开后对paramType、expr等继承属性继续操作。底层类型Token 与 Tokens理解MacroExpandParam离不开其属性的底层类型。Token是仓颉源码的最小组成单元见 Token 结构体public struct Token : ToBytes { public let kind: TokenKind public let pos: Position public let value: String public var delimiterNum: UInt16 1 }kind词法单元种类关键字、标识符、运算符、常量值等见 TokenKindpos在源码中的位置文件 ID、行号、列号见 Positionvalue词法单元的字面量值。Tokens则是对Token序列的封装见 Tokens支持迭代、按索引取值、拼接与toString()。宏的输入输出本质上都是Tokens这也是macroInputs、macroAttrs采用Tokens类型的原因——宏机制正是围绕词法单元序列的接收、改写与返回运转的。与宏节点家族的关系std.ast中宏相关节点共四类覆盖宏在源码中出现的四种位置节点继承关系典型形态关键差异MacroDeclDeclpublic macro M(input: Tokens): Tokens {...}宏的定义节点含block、funcParams、declType等MacroExpandDeclDeclM class A {}宏出现在声明位置MacroExpandExprExprM (a is Int64)宏出现在表达式位置含at与identifier属性MacroExpandParamFuncParamfunc foo (M a: Int64)宏出现在参数位置可复用FuncParam的参数语义值得注意的是MacroExpandExpr使用at操作符与identifier属性而MacroExpandParam与MacroExpandDecl一样使用fullIdentifier保存完整标识符——从源码结构可以推断这是为了在继承FuncParam/Decl时避免与父类已有的identifier属性声明节点标识符产生歧义特意改用完整标识符来承载宏名。实战解析与遍历宏调用参数节点结合 ast_samples/dump.md 中解析 dump的用法模式可以借助std.ast的解析函数与Visitor遍历机制处理MacroExpandParam节点。整体流程是先用parseProgram/parseDecl等解析函数将源码Tokens解析为 AST再通过Visitor定位到参数位置的宏调用最后读取或改写其属性。import std.ast.* // 通过 Visitor 定位 MacroExpandParam 节点 class ParamMacroVisitor : Visitor { public override func visit(macroExpandParam: MacroExpandParam): Unit { let id macroExpandParam.fullIdentifier.value let inputDecl macroExpandParam.macroInputDecl let inputs macroExpandParam.macroInputs println(macro: ${id}, input decl: ${inputDecl.toString()}, inputs: ${inputs.toString()}) } } main() { let tokens cangjieLex(func foo (M a: Int64) { }) let decl parseDecl(tokens) let visitor ParamMacroVisitor() decl.accept(visitor) }要点说明识别宏名读取fullIdentifier的value字段即可获得宏的完整名字含限定符读取输入macroInputs是宏将要处理的原始词法单元macroAttrs是属性式调用的参数读取改写结果macroInputDecl保存宏展开后解析得到的声明节点可直接作为后续改写与代码生成的基础校验结构括号类属性lParen/rParen/lSquare/rSquare可在改写时同步更新保证输出的Tokens与括号形态一致避免生成非法源码。关于宏的编译与调用流程可参考 ast_samples/context.md 中cjc macro_definition.cj --compile-macro先编译宏定义、再编译调用文件的完整步骤包级能力总览见 ast_package_overview.md。异常行为说明MacroExpandParam的多个属性在设置不合法词法单元时抛出 ASTExceptionlParen设置为非(的TokenrParen设置为非)的TokenlSquare设置为非[的TokenrSquare设置为非]的TokenmacroInputDecl在节点中不存在声明节点时访问也会抛出ASTException。编写宏工具时建议在设置括号类属性前先校验Token.kind如与 TokenKind 中的括号种类比对或对可能为空的macroInputDecl做存在性判断后再访问以保证宏展开过程的健壮性。小结MacroExpandParam是仓颉宏系统中覆盖参数位置宏调用的关键节点它通过fullIdentifier记录宏名通过macroInputs/macroAttrs分别承载普通调用与属性调用的输入通过macroInputDecl保存展开后的声明并以FuncParam为父类复用参数语义。结合 ast_package_classes.md、Token 与 Tokens 等配套类型即可在宏展开、AST 改写与代码生成等场景中完整驾驭这一节点。赞分享人工智能AI 技能文档开发工具【免费下载链接】DocAgent项目地址https://gitcode.com/Cangjie-SIG/DocAgent点击查看免费下载相关推荐仓颉语言 std.ast 宏调用节点详解MacroExpandDecl 类结构、构造方式与属性全解析仓颉语言 std.ast 宏调用节点详解MacroExpandDecl 类结构、构造方式与属性全解析 本文围绕仓颉标准库 std.ast 中表示 声明级宏调用人工智能AI 技能文档开发工具仓颉 AST 主构造函数节点 PrimaryCtorDecl 全解析类结构、属性语义与解析实战仓颉 AST 主构造函数节点 PrimaryCtorDecl 全解析类结构、属性语义与解析实战 PrimaryCtorDecl 是仓颉标准库 std.ast人工智能AI 技能文档开发工具仓颉 std.ast MacroExpandExpr 详解宏调用表达式 AST 节点的构造与属性操作仓颉 std.ast MacroExpandExpr 详解宏调用表达式 AST 节点的构造与属性操作 MacroExpandExpr 是仓颉语言标准库 std人工智能AI 技能文档开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑