Swift 抽象语法树

swift-ast master swift-lint master swift-transform pending

Travis CI Status codecov Swift 5.1 Swift Package Manager Platforms License

Swift 抽象语法树是一个旨在用 Swift 本身解析 Swift 编程语言 的项目。此实用程序的输出是源代码的相应 抽象语法树 (AST)。

此工具中生成的 AST 旨在用于各种场景。例如,源到源转换,如 swift-transform 和 linting 工具,如 swift-lint

重构、代码操作和优化也可以利用此 AST。

其他想法可能是 llvm-codegen 或 jvm-codegen(考虑 JSwift),它们可以消费 AST 并将其转换为二进制代码或字节码。我有一些概念验证项目,分别是 llswift-pocjswift-poc。如果您有兴趣参与codegen的开发,请发送电子邮件至 ryuichi@yanagiba.org

Swift 抽象语法树是 Yanagiba Project 的一部分。Yanagiba umbrella 项目是用 Swift 编写并为 Swift 服务的编译器模块、库和实用程序的工具链。


正在进行中

Swift 抽象语法树仍处于积极开发中。虽然许多功能已实现,但有些功能存在局限性。

欢迎提交关于新功能的 Pull Request,以及关于现有实现的问题和评论。

另请注意,Swift 语言正处于快速发展中,其语法尚不稳定。因此,细节可能会发生变化,以便跟上 Swift 的发展。

要求

安装

独立工具

要将其用作独立工具,请通过以下方式将此仓库克隆到您的本地计算机

git clone https://github.com/yanagiba/swift-ast

转到仓库文件夹,运行以下命令

swift build -c release

这将会在 .build/release 文件夹中生成一个 swift-ast 可执行文件。

添加到 swift 路径(可选)

可以将 swift-ast 复制到本地 Swift 安装的 bin 文件夹中。

例如,如果 which swift 输出

/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

那么您可以通过以下方式将 swift-ast 复制到其中

cp .build/release/swift-ast /Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-ast

完成此操作后,您可以通过在终端中直接调用 swift ast 来调用 swift-ast

嵌入到您的项目中

将 swift-ast 依赖项添加到 Package.swift

// swift-tools-version:5.0

import PackageDescription

let package = Package(
  name: "MyPackage",
  dependencies: [
    .package(url: "https://github.com/yanagiba/swift-ast.git", from: "0.19.9")
  ],
  targets: [
    .target(name: "MyTarget", dependencies: ["SwiftAST+Tooling"]),
  ],
  swiftLanguageVersions: [.v5]
)

用法

命令行

只需将文件路径附加到 swift-ast。它会将 AST 转储到控制台。

swift-ast path/to/Awesome.swift

可以使用一次调用解析多个文件

swift-ast path1/to1/foo.swift path2/to2/bar.swift ... path3/to3/main.swift

CLI 选项

默认情况下,AST 输出为纯文本格式,不带缩进,也没有关键字的颜色高亮。可以通过提供以下选项来更改输出格式

此外,可以提供 -github-issue 作为第一个参数选项,程序将尝试为您生成一个预填充内容的 GitHub issue 模板。

在您的代码中使用 AST

循环遍历 AST 节点

import AST
import Parser
import Source

do {
  let sourceFile = try SourceReader.read(at: filePath)
  let parser = Parser(source: sourceFile)
  let topLevelDecl = try parser.parse()

  for stmt in topLevelDecl.statements {
    // consume statement
  }
} catch {
  // handle errors
}

遍历 AST 节点

我们为所有 AST 节点提供了一个先序深度优先遍历实现。为了使用它,只需通过遵循 ASTVisitor 协议并为您感兴趣的 AST 节点编写 visit 方法来编写您的访问器。您也可以编写自己的遍历实现来覆盖默认行为。

traversevisit 方法返回 false 将停止遍历。

class MyVisitor : ASTVisitor {
  func visit(_ ifStmt: IfStatement) throws -> Bool {
    // visit this if statement

    return true
  }
}
let myVisitor = MyVisitor()
let topLevelDecl = MyParse.parse()
myVisitor.traverse(topLevelDecl)

开发

构建 & 运行

构建整个项目可以通过简单地调用

make

这等同于

swift build

该工具的开发版本可以通过以下方式调用

.build/debug/swift-ast path/to/file.swift

运行测试

编译并运行所有测试,通过

make test

联系方式

Ryuichi Sai

许可

Swift 抽象语法树在 Apache License 2.0 下可用。有关更多信息,请参阅 LICENSE 文件。