最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

以Golang為例詳解AST抽象語法樹的原理與實現(xiàn)

 更新時間:2024年01月17日 08:17:56   作者:燈火消逝的碼頭  
AST?使用樹狀結(jié)構(gòu)來表達編程語言的結(jié)構(gòu),樹中的每一個節(jié)點都表示源碼中的一個結(jié)構(gòu),本文將以GO語言為例,為大家介紹一下AST抽象語法樹的原理與實現(xiàn),希望對大家有所幫助

前言

各位同行有沒有想過一件事,一個程序文件,比如 hello.go 是如何被編譯器理解的,平常在編寫程序時,IDE 又是如何提供代碼提示的。在這奧妙無窮的背后, AST(Abstract Syntax Tree)抽象語法樹功不可沒,他站在每一行程序的身后,默默無聞的工作,為繁榮的互聯(lián)網(wǎng)世界立下了汗馬功勞。

AST 抽象語法樹

AST 使用樹狀結(jié)構(gòu)來表達編程語言的結(jié)構(gòu),樹中的每一個節(jié)點都表示源碼中的一個結(jié)構(gòu)。聽到這或許你的心里會咯噔一下,其實說通俗一點,在源代碼解析后會得到一串數(shù)據(jù),這個數(shù)據(jù)自然的呈現(xiàn)樹狀結(jié)構(gòu),它被稱之為 CST(Concrete Syntax Tree) 具體語法樹,在 CST 的基礎(chǔ)上保留核心結(jié)構(gòu)。忽略一些不重要的結(jié)構(gòu),比如標點符號,空白符,括號等,就得到了 AST。

如何生成 AST 

生成 AST 大概需要兩個步驟,詞法分析lexical analysis和語法分析syntactic analysis 。

詞法分析 lexical analysis

lexical analysis 簡稱 lexer ,它表示字符串序列,也就是我們的源代碼轉(zhuǎn)化為 token 的過程,進行詞法分析的工具叫做詞法分析器(lexical analyzer,簡稱lexer),也叫掃描器(scanner)。Go 語言的 go/scanner 包提供詞法分析。 

func ScannerDemo() {
	// 源代碼
	src := []byte(`
func demo() {
	fmt.Println("When you are old and gray and full of sleep")
}
`)

	// 初始化標記
	var s scanner.Scanner
	fset := token.NewFileSet()
	file := fset.AddFile("", fset.Base(), len(src))
	s.Init(file, src, nil, scanner.ScanComments)

	// Scan 進行掃碼并打印出結(jié)果
	for {
		pos, tok, lit := s.Scan()
		if tok == token.EOF {
			break
		}
		fmt.Printf("%s\t%s\t%q\n", fset.Position(pos), tok, lit)
	}
}

打印的結(jié)果我們接著往下看。

標記 token

標記(token)  是詞法分析后留下的產(chǎn)物,是構(gòu)成源代碼的最小單位,但是這些 token 之間沒有任何邏輯關(guān)系。以上述代碼為例:

func demo() {
	fmt.Println("When you are old and gray and full of sleep")
}

經(jīng)過詞法分析后,會得到:

tokenliteral(字面量,以string表示)
func"func"
IDENT"demo"
(""
)""
{""
IDENT"fmt"
.""
IDENT"Println"
(""
STRING"\"When you are old and gray and full of sleep\""
)""
;"\n"
}""
;"\n"

在 Go 語言中,如果 token 類型就是一個字面量,例如整型,字符串類型等,那么它的值就是相對應的值,比如上表的 STRING;如果 token 是 Go 的關(guān)鍵詞,那么它的值就是關(guān)鍵詞,比如上表的 fun;對于分號,它的值則是換行符;其他 token 類要么是不合法的,如果是合法的,則值為空字符串,比如上表的 {。

語法分析 syntactic analysis

不具備邏輯關(guān)系的 token 經(jīng)過語法分析(syntactic analysis,也叫 parsing)就可以得到具有邏輯關(guān)系的 CST 具體語法樹,然后對 CST 進行分析提煉即可得到 AST 抽象語法樹。完成語法分析的工具叫做語法分析器(parser)。Go 語言的 go/parser 提供語法分析。

func ParserDemo() {
	src := `
package main
`
	fset := token.NewFileSet()
	// 如果 src 為 nil,則使用第二個參數(shù),它可以是一個 .go 文件地址
	f, err := parser.ParseFile(fset, "", src, 0)
	if err != nil {
		panic(err)
	}

	ast.Print(fset, f)
}

打印出來的 AST:

 0  *ast.File {
 1  .  Package: 2:1
 2  .  Name: *ast.Ident {
 3  .  .  NamePos: 2:9
 4  .  .  Name: "main"
 5  .  }
 6  .  FileStart: 1:1
 7  .  FileEnd: 2:14
 8  .  Scope: *ast.Scope {
 9  .  .  Objects: map[string]*ast.Object (len = 0) {}
10  .  }
11  }

它包含了源代碼的結(jié)構(gòu)信息,看起來像一個 JSON。

總結(jié)

源代碼經(jīng)過詞法分析后得到 token(標記),token 經(jīng)過語法分析得到 CST 具體語法樹,在 CST 上創(chuàng)建 AST 抽象語法樹。 來個圖圖或許更直觀:

Go 的抽象語法樹

這里我們以一個具體的例子來看:從 go 代碼中提取所有結(jié)構(gòu)體的名稱。

// 源碼
type A struct{}
type B struct{}
type C struct{}
func ExampleGetStructName() {
	fileSet := token.NewFileSet()
	node, err := parser.ParseFile(fileSet, "demo.go", nil, parser.ParseComments)
	if err != nil {
		return
	}

	ast.Inspect(node, func(n ast.Node) bool {
		if v, ok := n.(*ast.TypeSpec); ok {
			fmt.Println(v.Name.Name)
		}
		return true
	})
	// Output:
	// A
	// B
	// C
}

到此這篇關(guān)于以Golang為例詳解AST抽象語法樹的原理與實現(xiàn)的文章就介紹到這了,更多相關(guān)Go AST抽象語法樹內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang內(nèi)存模型教科書級講解

    Golang內(nèi)存模型教科書級講解

    go官方介紹go內(nèi)存模型的時候說:探究在什么條件下,goroutine?在讀取一個變量的值的時,能夠看到其它?goroutine?對這個變量進行的寫的結(jié)果,Go內(nèi)存模型規(guī)定了一些條件,在這些條件下,在一個goroutine中讀取變量返回的值能夠確保是另一個goroutine中對該變量寫入的值
    2023-03-03
  • golang中進行條件編譯的示例詳解

    golang中進行條件編譯的示例詳解

    條件編譯顧名思義就是在編譯時讓代碼中的一部分生效或者失效,從而控制編譯時的代碼執(zhí)行路徑,進而影響編譯出來的程序的行為,下面我們就來看看如何在golang中進行條件編譯吧
    2025-03-03
  • go數(shù)據(jù)結(jié)構(gòu)和算法BitMap原理及實現(xiàn)示例

    go數(shù)據(jù)結(jié)構(gòu)和算法BitMap原理及實現(xiàn)示例

    這篇文章主要為大家介紹了go數(shù)據(jù)結(jié)構(gòu)和算法BitMap原理及實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Go使用Redis實現(xiàn)分布式鎖的常見方法

    Go使用Redis實現(xiàn)分布式鎖的常見方法

    Redis?提供了一些原語,可以幫助我們實現(xiàn)高效的分布式鎖,下邊是使用?Redis?實現(xiàn)分布式鎖的一種常見方法,通過代碼示例給大家介紹的非常詳細,具有一定的參考價值,需要的朋友可以參考下
    2024-11-11
  • golang 如何用反射reflect操作結(jié)構(gòu)體

    golang 如何用反射reflect操作結(jié)構(gòu)體

    這篇文章主要介紹了golang 用反射reflect操作結(jié)構(gòu)體的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go語言CSP并發(fā)模型goroutine及channel底層實現(xiàn)原理

    Go語言CSP并發(fā)模型goroutine及channel底層實現(xiàn)原理

    這篇文章主要為大家介紹了Go語言CSP并發(fā)模型goroutine?channel底層實現(xiàn)原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • Go語言fmt庫詳解與應用實例(格式化輸入輸出功能)

    Go語言fmt庫詳解與應用實例(格式化輸入輸出功能)

    fmt庫是Go語言中一個強大而靈活的庫,提供了豐富的格式化輸入輸出功能,通過本文的介紹和實例演示,相信你對fmt庫的使用有了更深的理解,感興趣的朋友一起看看吧
    2023-10-10
  • golang語言map全方位介紹

    golang語言map全方位介紹

    本文主要介紹了golang語言map全方位介紹,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Goland IDEA項目多開設(shè)置方式

    Goland IDEA項目多開設(shè)置方式

    這篇文章主要介紹了Goland IDEA項目多開設(shè)置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Go操作etcd的實現(xiàn)示例

    Go操作etcd的實現(xiàn)示例

    etcd是近幾年比較火熱的一個開源的、分布式的鍵值對數(shù)據(jù)存儲系統(tǒng),提供共享配置、服務的注冊和發(fā)現(xiàn),本文主要介紹etcd的安裝和使用,感興趣的可以了解一下
    2021-09-09

最新評論

博兴县| 临沂市| 奈曼旗| 万荣县| 东乌珠穆沁旗| 岑溪市| 永靖县| 盐城市| 北辰区| 衡阳市| 深圳市| 团风县| 杭锦后旗| 宜兴市| 信阳市| 徐水县| 渝中区| 墨脱县| 文水县| 义马市| 龙胜| 靖西县| 奈曼旗| 肥乡县| 太仆寺旗| 天柱县| 准格尔旗| 武宣县| 青浦区| 长宁区| 兰考县| 华安县| 公安县| 绥宁县| 苗栗县| 沙湾县| 肇庆市| 怀远县| 应城市| 鄂伦春自治旗| 汝南县|