跟我一起学“仓颉”编程语言-AST
·
一、AST节点
Node类型是所有AST节点的根节点,是所有其他AST节点类型的直接或间接父类。Decl类型是所有声明节点的根节点,变量定义(VarDecl)、函数定义(FuncDecl)、类定义(ClassDecl)、扩展定义(ExtendDecl)、宏定义(MacroDecl)都是Decl类型的子类型。Expr类型是所有表达式节点的根节点,TypeNode节点是所有类型节点的根节点,Pattern类型表示所有模式匹配节点的根节点。
二、Tokens与AST节点的相互转换
Tokens类型转AST类型,使用parse开头的函数,AST类型转Tokens类型,可以使用toTokens函数
package Study
// 导包
import Study.define.*
import std.ast.*
main () {
let tokens: Tokens = quote(var num = 3 + 5)
try {
let decl: Decl = parseDecl(tokens)
println(decl.toTokens())
} catch (_) {
println("无法转换")
}
}
三、BinaryExpr节点
BinaryExpr表示二元表达式节点
package Study
// 导包
import Study.define.*
import std.ast.*
main () {
let tokens = quote(2 + 4)
let expr:BinaryExpr = BinaryExpr(tokens)
println(expr.dump())
}
四、Decl节点
package Study
// 导包
import Study.define.*
import std.ast.*
main () {
let tokens = quote(
public func hi() {
println("你好")
}
)
let decl = parseDecl(tokens)
// 获取修饰符
for (modifier in decl.modifiers) {
modifier.dump()
}
// 获取关键字
decl.keyword.dump()
// 获取函数名
decl.identifier.dump()
}
五、VarDecl节点
VarDecl类表示变量声明对应的AST节点
package Study
// 导包
import Study.define.*
import std.ast.*
main () {
let tokens = quote(public static var num: Int64 = 114514)
let varDecl = VarDecl(tokens)
print("修饰符: ")
for (modifier in varDecl.modifiers) {
println("\t ${modifier.keyword.dump()}")
}
println("\n关键字: ${varDecl.keyword.value}")
println("变量名: ${varDecl.identifier.value}")
println("变量类型: ")
varDecl.declType.dump()
println("初始值")
varDecl.expr.dump()
}
六、FuncDecl节点
funcParams可以查看函数的参数列表
package Study
// 导包
import Study.define.*
import std.ast.*
main () {
let tokens = quote(
func demo(param!: Int64 = 10) {
println("param=${param}")
}
)
let funcDecl = FuncDecl(tokens)
// 获取函数唯一参数
let funcParam = funcDecl.funcParams[0]
println("函数名: ${funcParam.identifier.value}")
println("参数类型: ${funcParam.paramType.toTokens()}")
if (funcParam.not.value == "!") {
println("是命名参数")
if (funcParam.colon.value == ":") {
println("默认值: ${funcParam.expr.toTokens()}")
} else {
println("无默认值")
}
} else {
println("不是命名参数")
}
}
block属性表示函数体
package Study
// 导包
import Study.define.*
import std.ast.*
main () {
let tokens = quote(
public func add(x: Int64, y: Int64) {
let sum = x + y
return sum
}
)
let funcDecl = FuncDecl(tokens)
let funcbody = funcDecl.block.nodes
for (body in funcbody) {
println(body.toTokens())
}
}
七、ClassDecl节点
ClassDecl类表示类声明对应的AST节点,该类继承了Decl类
package Study
// 导包
import Study.define.*
import std.ast.*
main () {
let tokens = quote(
class Person {
Person(var name: String, var age: Int64, var sex: String){}
init(name: String, age: Int64) {
this.name = name
this.age = age
}
func show() {
println("姓名: ${this.name}, 年龄: ${this.age}, 性别: ${this.sex}")
}
}
)
let classDecl = ClassDecl(tokens)
for (body in classDecl.body.decls) {
if (body is VarDecl) {
println("变量声明: \n${body.toTokens()}")
}
if (body is PrimaryCtorDecl) {
let primaryInit = (body as PrimaryCtorDecl).getOrThrow()
println("主构造函数: ")
println("函数名: ${primaryInit.identifier.value}")
println("参数列表: ${primaryInit.funcParams.toTokens()}")
println("参数列表中的成员变量参数")
let params = primaryInit.funcParams
for (param in params) {
if (param.isMemberParam()) {
println("${param.identifier.value}")
}
}
}
if (body is FuncDecl) {
let initBody = (body as FuncDecl).getOrThrow()
if (initBody.identifier.value == "init") {
println("普通构造函数:")
println("函数名: ${initBody.identifier.value}")
println("参数列表: ${initBody.funcParams.toTokens()}")
}
println("函数声明: \n${body.toTokens()}")
}
}
}
八、遍历AST节点
package Study
// 导包
import Study.define.*
import std.ast.*
class MyVisitor <: Visitor {
protected override func visit(funcDecl: FuncDecl) {
println("函数名: ${funcDecl.identifier.value}")
// breakTraverse用于重写visit函数,子节点将不会被调用
breakTraverse()
}
protected override func visit(incOrDecExpr: IncOrDecExpr) {
println(incOrDecExpr.toTokens())
}
}
main () {
let tokens = quote(
class Demo {
let x: Int64 = 3
let y: Int64 = 4
func add() {
this.x + this.y
}
func sub() {
this.x - this.y
}
}
)
let classDecl = ClassDecl(tokens)
classDecl.traverse(MyVisitor())
}
九、小结
本章为大家详细的介绍了仓颉编程语言中AST的内容,下一章,为大家带来非属性宏和属性宏的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉服务端开发有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!
昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链
更多推荐

所有评论(0)