iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0
自我挑戰組

自己的 Leak, 自己抓(swift)系列 第 5

SwiftSyntax 前導 (AST)

  • 分享至 

  • xImage
  •  

SwiftSyntax 前導 (AST)

在前面的第四天,我們已經學會了如何取得特定 Modulefile list。現在,我們將進一步使用另一個 library,稱為 SwiftSyntax,通過它,我們可以訪問 Swift 的抽象語法樹(AST)。

編譯流程

首先,讓我們了解一下編譯程式碼的過程。程式碼在編譯過程中會經過多個步驟,我們可以參考以下文章 Day3.編譯器運作流程介紹 中的圖示:

通過這張圖,我們可以看到,在獲得 AST 之前,程式碼必須經過兩個主要步驟,即 Lex語法分析


Lex

Lex 步驟將我們的程式碼進行 token 化,將程式碼拆分為一系列的 token:

let code = """
let test = process(x)
"""

func lex(_ code: String) -> [String] {...}
lex(code)
/*
"let"
"test"
"="
"process"
"("
"x"
")"
 */

語法分析

在進行 語法分析 之前,我們需要定義一些簡單的語法結構,這些結構將幫助我們轉換程式碼為 AST:

這個範例將能夠解析語法,變數宣告以及函式呼叫。

indirect enum Expr {
    case idDecl(id: String)
    case varDecl(
        letKeyword: Keyword,
        varName: Expr,
        equal: Operator,
        content: Expr
    )
    case functionCall(
        functionName: Expr,
        leftParent: String,
        args: [Expr],
        rightParent: String,
    )
}

enum Keyword {
    case `let`
}

enum Operator {
    case equal
}

然後,我們可以將程式碼轉換為 AST:

/// let test = process(x)
func parse(_ tokens: [String]) -> [Expr] {...}

let ast: [Expr] = [
    .varDecl(
        letKeyword: .let,
        varName: .id("test"),
        equal: .equal,
        content: .functionCall(
            functionName: .id("process"),
            leftParent: "(",
            args: [.id("x")],
            rightParent: ")",
        )
    )
]

最終,我們獲得了一個樹狀結構,稱為抽象語法樹(AST),如下所示:

https://ithelp.ithome.com.tw/upload/images/20230917/20158030QPedh0TCq5.png


如果我們將葉子節點(leaf)連接起來,就會獲得剛剛的程式碼:

let test = process(x)

上一篇
需要掃描哪幾份檔案
下一篇
初入 SwiftSyntax
系列文
自己的 Leak, 自己抓(swift)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言