人工智能AI 技能文档开发工具【免费下载链接】DocAgent项目地址https://gitcode.com/Cangjie-SIG/DocAgent点击查看免费下载BinaryExpr是仓颉标准库std.ast包中表示二元操作表达式如a b、x - y的抽象语法树AST节点类。本文以 BinaryExpr 类文档 为骨架结合该包内 类 API 详解 与 官方示例 源码系统讲解其声明结构、两种构造方式、三个成员属性leftExpr/op/rightExpr的读写语义并给出在宏展开、语法树遍历与节点改写场景下的实战用法帮助读者在解析仓颉源码时准确识别与操作二元表达式。一、BinaryExpr 在 std.ast 中的定位std.ast包是仓颉语言的语法解析器与语法树节点库它可将仓颉源码的词法单元Tokens解析为抽象语法树节点对象包总览 中明确给出了parseExpr、parseDecl、parseProgram等解析入口。BinaryExpr正是表达式中最常见的节点类型之一凡形如a b、a - b的二元运算都会在语法树中以它表示。在节点的继承体系中它的位置如下Node所有仓颉语法树节点的父类Expr所有表达式节点的父类继承自NodeBinaryExpr继承自Expr表示二元操作表达式。BinaryExpr的类声明在 ast_package_classes.md 中给出public class BinaryExpr : Expr { public init() public init(inputs: Tokens) }它只暴露了两个构造函数没有额外的公开成员方法——对节点的操作全部通过三个public mut prop属性完成这体现了 AST 节点“结构化数据 可读写属性”的设计风格。二、两种构造方式默认构造与从词法单元构造1.init()默认构造构造一个空的BinaryExpr对象。创建后三个属性处于默认状态通常用于“自底向上”手工搭建语法树随后通过属性赋值填充左右表达式与操作符。2.init(inputs: Tokens)从词法单元构造public init(inputs: Tokens)传入一组词法单元集合Tokens由构造器内部完成语法解析并生成BinaryExpr节点。文档明确指出当输入的Tokens无法构造为BinaryExpr节点时会抛出 ASTException。例如传入的是一元表达式-a或赋值表达式a b的词法单元构造就会失败因为它们的节点类型分别是UnaryExpr与AssignExpr。三、三个核心属性leftExpr / op / rightExpr属性原型功能类型leftExprpublic mut prop leftExpr: Expr获取或设置操作符左侧的表达式节点Exproppublic mut prop op: Token获取或设置二元操作符TokenrightExprpublic mut prop rightExpr: Expr获取或设置操作符右侧的表达式节点Expr三者均为mut prop即可读可写。这一设计意味着对一个已解析出的BinaryExpr开发者既可以只读地提取其运算结构如宏中判断“这个加法操作符是什么”也可以直接改写其子节点如把a b改成a - b。其中op的类型是词法单元 Token。一个Token由kind词法单元类型见 TokenKind、value字面量值与pos源码位置三部分组成因此判断二元操作符时既可以比对op.value如也可以比对op.kind如ADD。四、op 属性的取值二元操作符与 TokenKind 对照op能承接的运算符种类由 TokenKind 定义。从 TokenKind_enum.md 的枚举值可以归纳出仓颉中常见的二元操作符及其对应的TokenKind如下操作符字面量TokenKind类别加ADD算术减-SUB算术乘*MUL算术除/DIV算术取模%MOD算术幂**EXP算术逻辑与AND逻辑逻辑或\|\|OR逻辑合并??COALESCING空值合并管道\|PIPELINE管道操作函数组合~COMPOSITION组合操作按位与BITAND位运算按位或\|BITOR位运算按位异或^BITXOR位运算左移LSHIFT位运算右移RSHIFT位运算等于EQUAL比较不等于!NOTEQ比较小于LT比较大于GT比较小于等于LE比较大于等于GE比较需要注意的边界情况并非所有二元符号都归BinaryExpr管辖。根据 类 API 详解 中各节点类的说明赋值类操作、等由 AssignExpr 表示区间操作..、..由 RangeExpr 表示类型检查is/as分别由 IsExpr 与 AsExpr 表示。从源码结构可以推断解析器会根据操作符种类分发到不同的节点类型只有“纯二元运算”才落到BinaryExpr。五、实战用 parseExpr 从源码解析出 BinaryExpr在宏或工具代码中最常见的做法是先通过 cangjieLex 或quote得到词法单元再用 parseExpr 解析出表达式节点最后用as类型转换取到BinaryExpr。参考 parse.md 示例 的模式写法如下import std.ast.* main() { let input: Tokens quote( a b * 2 ) let expr parseExpr(input) // 获取一个 Expr 表达式节点 var binExpr match (expr as BinaryExpr) { // 将表达式节点转换为 BinaryExpr case Some(v) v case None throw Exception() } // 读取操作符信息 println(op kind: ${binExpr.op.kind} value: ${binExpr.op.value}) println(left expr toTokens: ${binExpr.leftExpr.toTokens()}) println(right expr toTokens: ${binExpr.rightExpr.toTokens()}) 0 }结合 Token_struct.md 对Token的定义op.kind返回ADD这类枚举值op.value返回原始字符如op.pos则记录了操作符在源码中的行列位置——这些信息在生成诊断信息时非常有用。六、改写 BinaryExpr属性赋值与 toTokens 的括号规则由于三个属性都是mut prop可以直接对已解析的节点做“就地手术”。例如把a * b的左操作数从a改为a 1import std.ast.* main() { let input: Tokens quote( a * b ) let expr parseExpr(input) var binExpr match (expr as BinaryExpr) { case Some(v) v case None throw Exception() } // 改写左侧表达式将 a 替换为 a 1 binExpr.leftExpr parseExpr(quote(a 1)) // 序列化回词法单元并打印 println(binExpr.toTokens()) 0 }这里有一个关键行为Expr 类说明 中专门强调表达式节点的toTokens方法会根据操作符优先级添加括号。文档给出的原始例子是已有BinaryExpr节点a * b把左表达式内容a修改为a 1后toTokens会为左表达式自动补括号输出(a 1) * b从而保证改写后的文本依然保持正确的运算语义。这说明BinaryExpr的节点结构 toTokens序列化构成了“解析—改写—还原”的完整闭环是宏代码生成的重要基础。七、在 Visitor 遍历与宏场景中使用 BinaryExpr1. 继承 Visitor 定向处理traverse.md 示例 展示了通过继承 Visitor 并重写visit函数实现定向遍历的做法。同样的机制适用于BinaryExpr重写visit(binaryExpr: BinaryExpr)即可对语法树中所有二元表达式做统一处理例如统计某个文件中加法运算的个数、或收集所有出现??合并操作符的位置import std.ast.* class BinaryCollector : Visitor { public var count 0 override public func visit(binaryExpr: BinaryExpr) { if (binaryExpr.op.kind TokenKind.ADD) { count } return } } main(): Int64 { let input: Tokens quote( var r a b c ) let decl parseDecl(input) let collector BinaryCollector() decl.traverse(collector) println(ADD count is ${collector.count}) 0 }2. 在宏展开中生成与校验表达式std.ast的宏能力建立在“词法单元Tokens↔ AST 节点”互转之上context.md 示例 展示了宏内quote与parseExpr的配合用法。宏展开时可以先parseExpr拿到BinaryExpr检查其op.kind是否满足预期例如只允许算术运算不满足则通过 diagReport 报错满足后也可改写子表达式再toTokens()输出新的代码文本实现“语义化”的代码生成。八、关联文档与进一步阅读围绕BinaryExpr的更多细节与配套资料可在当前仓库中继续查阅类定义与属性/构造的完整原型std/ast/ast_package_api/ast_package_classes.md机器可读的 API 元数据BinaryExpr_class.json词法单元结构op属性的类型Token_struct.md操作符枚举全集op.kind的取值范围TokenKind_enum.md父类Expr与toTokens括号规则Expr_class.md同类节点对照赋值表达式 AssignExpr_class.md、一元表达式 UnaryExpr_class.md解析、操作、遍历示例parse.md、operate.md、traverse.md、context.md包级 API 总览std/ast/readme.md 与 ast_package_overview.md掌握BinaryExpr的构造、属性读写与toTokens行为即可在仓颉宏与 AST 工具链中自由识别、校验和生成二元运算代码是深入仓颉元编程的第一步。赞分享人工智能AI 技能文档开发工具【免费下载链接】DocAgent项目地址https://gitcode.com/Cangjie-SIG/DocAgent点击查看免费下载相关推荐仓颉 std.ast 语法树节点解析ArrayLiteral 数组字面量节点的构造、属性与实战用法仓颉 std.ast 语法树节点解析ArrayLiteral 数组字面量节点的构造、属性与实战用法 ArrayLiteral 是仓颉标准库 std.ast 包人工智能AI 技能文档开发工具仓颉语言 std.ast 包 AST 节点类全解析语法树类型体系与宏编程实践指南仓颉语言 std.ast 包 AST 节点类全解析语法树类型体系与宏编程实践指南 导读 仓颉编程语言的标准库 std.ast 包提供了源码语法解析器与完整的文档知识库教程OpenHarmony仓颉语言宏开发语法节点std.ast的解析、修改与 quote 插值实战仓颉语言宏开发语法节点std.ast的解析、修改与 quote 插值实战 本文深入讲解仓颉Cangjie编程语言宏体系中最重要的数据类型—— std.文档编程语言上一篇JustAuth中的位运算RandomUtil如何生成高效随机数下一篇WLED固件开发指南从源码编译到OTA更新全流程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考