此模块为 tree-sitter 解析库提供 Swift 绑定。
将其作为依赖项添加到 Package.swift
文件中。
.package(url: "https://github.com/viktorstrate/swift-tree-sitter", from: "1.0.0")
或者从 Xcode 导航到 File
-> Swift Packages
-> Add Package Dependency...
,然后输入此 URL
https://github.com/viktorstrate/swift-tree-sitter
如果你想在运行时从 .bundles
动态加载语言,你必须直接将其导入到 Xcode,因为 Swift 包管理器不支持 Mac bundle。
要做到这一点,请下载项目并将包含 SwiftTreeSitter.xcodeproj
文件的文件夹拖到 Xcode 项目的侧边栏中。
首先,你需要设置 Parser 并指定要使用的语言。
let javascript = try STSLanguage(fromPreBundle: .javascript)
let parser = STSParser(language: javascript)
然后你可以解析一些源代码。
let sourceCode = "let x = 1; console.log(x);";
let tree = parser.parse(string: sourceCode, oldTree: nil)!
print(tree.rootNode.sExpressionString!)
// (program
// (lexical_declaration
// (variable_declarator name: (identifier) value: (number)))
// (expression_statement
// (call_expression function:
// (member_expression object: (identifier)
// property: (property_identifier))
// arguments: (arguments (identifier)))))
检查语法树。
let callExpression = tree.rootNode.child(at: 1).firstChild(forOffset: 0)
print("type:\t\(callExpression.type)")
print("start point:\t\(callExpression.startPoint)")
print("end point:\t\(callExpression.endPoint)")
print("start byte:\t\(callExpression.startByte)")
print("end byte:\t\(callExpression.endByte)")
// type: call_expression
// start point: STSPoint(row: 0, column: 11)
// end point: STSPoint(row: 0, column: 25)
// start byte: 11
// end byte: 25
如果你的源代码发生更改,你可以更新语法树。这将比从头重新计算树花费更少的时间。
// replace let with const
let newSourceCode = "const x = 1; console.log(x);";
tree.edit(
STSInputEdit(
startByte: 0,
oldEndByte: 3,
newEndByte: 5,
startPoint: STSPoint(row: 0, column: 0),
oldEndPoint: STSPoint(row: 0, column: 3),
newEndPoint: STSPoint(row: 0, column: 5)
))
let newTree = parser.parse(string: newSourceCode, oldTree: tree)
如果你的文本存储在自定义数据源中,你可以通过将回调函数传递给 .parse()
而不是 String
来解析它。
let sourceLines = [
"let x = 1;\n",
"console.log(x);\n"
]
let tree = parser.parse(callback: { (byte, point) -> [Int8] in
if (point.row >= sourceLines.count) {
return []
}
let line = sourceLines[Int(point.row)]
let index = line.index(line.startIndex, offsetBy: Int(point.column))
let slice = line[index...]
let array = Array(slice.utf8).map { Int8($0) }
return array
}, oldTree: nil)