日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言编译器好玩的代码,读懂这4个函数,528行代码,你也可以实现一个C语言编译器...

發布時間:2024/8/1 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言编译器好玩的代码,读懂这4个函数,528行代码,你也可以实现一个C语言编译器... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

自從華為方舟編譯器橫空出世,一舉成為全民網紅之后,一下子點燃了大家對編譯器的熱情。不過,對于大多數人來說,編譯器依舊是遙不可及的神秘存在。

今天,介紹一個國外大牛寫的C語言編譯器 - C4,揭開編譯器的神秘面紗。原來實現一個具備基本功能的編譯器,竟是如此簡單!

C4:4個函數實現的C語言編譯器

C4, C in four functions。

它是一個C語言編譯器項目(項目地址在文末),整個實現只有:

一個C語言源碼文件528行C語言代碼4個函數

僅此而已。

讀懂這4個函數,528行代碼,你也可以實現一個C語言編譯器-1.jpg (34.72 KB, 下載次數: 0)

2020-7-17 12:33 上傳

C4代碼倉庫

它簡潔,卻不簡單。

它具備完整的詞法分析、語法分析、簡單的語義檢查、代碼生成、運行時環境(即虛擬機)。

與常見的C編譯器不同的是,它把C語言源程序編譯成字節碼(bytecode),然后在一個精簡的虛擬機中解釋執行。

你以為這樣就完了?不,它令人稱道之處遠不止如此!

C4:可以自舉的C語言編譯器

若只是精簡,或許它還并不那么令人驚奇,畢竟網上有很多類似的編譯器項目,其中不乏一些非常簡單優雅,且非常出色的項目。

然而,C4最驚艷的地方是,它可以自舉。

所謂自舉,簡單來說,就是自己編譯自己。當然,最初始的那個C4編譯器的可執行文件,還是必須要通過GCC、Clang等編譯器進行編譯生成。

我們下面演示一下“Hello, World!”的例子,和C4自舉的例子。

Hello, World示例

先用GCC把C4編譯成可執行文件:

gcc??c4.c??-o??c4

運行“Hello, World!”測試程序hello.c:

讀懂這4個函數,528行代碼,你也可以實現一個C語言編譯器-2.jpg (12.31 KB, 下載次數: 0)

2020-7-17 12:33 上傳

結果如圖:

讀懂這4個函數,528行代碼,你也可以實現一個C語言編譯器-3.jpg (34.83 KB, 下載次數: 0)

2020-7-17 12:33 上傳

其中,“hello, world”是hello.c 輸出的,“exit(0) cycle = 9”是c4編譯器輸出的,表示程序正常運行結束,hello.c一共生成9條指令。

C4的自舉示例

我們用GCC編譯c4.c生成了可執行文件c4,我們稱之為編譯器A,然后用編譯器A來編譯c4的源碼c4.c,則生成一個編譯器B,然后再用編譯器B來編譯執行hello.c。

命令如下:

./c4 c4.c hello.c

結果如圖:

讀懂這4個函數,528行代碼,你也可以實現一個C語言編譯器-4.jpg (38.96 KB, 下載次數: 0)

2020-7-17 12:33 上傳

C4自舉執行

還可以這樣:

./c4??c4.c??c4.c??hello.c

也就是GCC編譯生成的c4是編譯器A,./c4 c4.c生成的是編譯器B, ./c4 c4.c c4.c編譯生成的則是編譯器C,最后用編譯器C來編譯運行hello.c。

讀懂這4個函數,528行代碼,你也可以實現一個C語言編譯器-5.jpg (34.62 KB, 下載次數: 0)

2020-7-17 12:33 上傳

C4遞歸自舉

理論上可以一直遞歸下去。只不過,從圖中可以看出,遞歸的層次越深,生成的字節碼越多,執行所需的時間也越多。

C4實現的C語言子集

C4致力于用最少的代碼,實現一個可以自舉的C編譯器。它的整個實現只有4個函數組成,可想而知,它不可能完整的實現整個C語言的規范,它只實現了C語言的一個子集。

數據類型

char int 指針 枚舉(enum) 數組 字符串

不支持struct、typedef、union等數據類型。

語句結構

if-else控制語句while循環語句return語句函數

不支持do-while、switch-case、for、continue、break、goto等語句結構。

運算符

它支持除+=、%=、<<=、&=等符合運算符之外的幾乎所有運算符。包括:

算術運算符關系運算符邏輯運算符位運算符賦值運算符雜項運算符(如三元運算符?:)

內建庫函數

C4編譯器實現時用到了一些系統庫函數,因此,為了實現自舉,它也內建支持了幾個庫函數。包括:

open、read、close、printf、malloc、free、memset、memcmp、exit

需要注意的是,它不支持以#開頭的預處理命令,如#include、#define、#if等。

代碼注釋只支持“//”開頭的單行注釋,不支持“/* */”標記的多行注釋形式。

與傳統的C語言編譯器相比,C4在實現上有其獨到之處。

下面,先簡單介紹一些傳統編譯器的實現過程。

傳統典型編譯器的實現

典型的編譯器的實現,一般都會有下面幾個過程:

詞法分析語法分析語義分析中間代碼生成代碼優化機器代碼生成

如GCC、Clang、華為方舟編譯器等均是如此。

讀懂這4個函數,528行代碼,你也可以實現一個C語言編譯器-6.jpg (30.59 KB, 下載次數: 0)

2020-7-17 12:33 上傳

這些階段,會對代碼進行多次掃描。這里的代碼,包括文本形式的源代碼、語法樹、中間代碼等表示形式。

典型的實現中,詞法分析和語法分析通常會糅合在一起,在語法分析時,調用詞法分析器逐個取得token。因此,理論上講,詞法分析和語法分析階段,只需要對源碼掃描一遍即可,并生成語法樹,有時也叫抽象語法樹(Abstract Syntax Tree)。

語義分析階段操作的主要對象就是這棵樹,至少要對這棵樹掃描一遍。有些實現中,在進行語義檢查的同時也會直接生成中間代碼。

在代碼優化階段,根據編譯器優化的力度的不同,可能會對中間代碼進行多次掃描。

這里所謂的“掃描一遍”,在編譯器術語中一般稱為pass。對LLVM有了解的朋友應該知道,LLVM中每一種類型的優化都是一個pass,要應用多種優化技術,就需要有多個pass。

C4的獨具特色之處

作為追求極簡主義的C4編譯器來說,它在實現上有很多獨具特色之處。

對C源碼解釋執行

傳統的C語言編譯器,最終都把C語言源碼編譯成可執行文件,也就是二進制的機器碼。

而C4則是把C語言源碼先編譯成其專門設計的字節碼(bytecode),然后直接在虛擬機中解釋執行。

C4設計了39個字節碼指令,其中大部分與匯編語言中的指令有些類似,主要是內存加載指令,算術運算指令等,此外,還包含了為支持內建的庫函數而專門設計的9條特殊的庫函數調用指令。

它的虛擬機是典型的棧式虛擬機(Java虛擬機也是典型的棧式虛擬機,早期的Lua也是棧式虛擬機,但最新的Lua 5.x采用寄存器虛擬機)。

我們可以使用-d命令,把生成的字節碼dump出來。下圖是hello.c的字節碼:

讀懂這4個函數,528行代碼,你也可以實現一個C語言編譯器-7.jpg (35.49 KB, 下載次數: 0)

2020-7-17 12:33 上傳

對源碼只掃描一遍

與傳統的編譯器實現不同,C4它把詞法分析、語法分析、語義分析、代碼生成這幾個步驟巧妙的結合在一起,在把C語言源碼編譯成字節碼的整個過程中,只掃描了一遍源碼。

Lua的解釋器也是采用對源碼掃描一遍的方式,因此,C4和Lua的性能都相當不錯。

C4源碼的可讀性

對于C4的實現,網上也有一些討論。有人認為C4的實現非常簡潔、易讀,也有人認為C4的實現稍顯晦澀。

我個人認為,C4的實現確實非常簡潔,畢竟只有4個函數,500多行代碼。但是要真正完全理解,需要有一定的編譯原理基礎知識。

比如C4的語法分析過程中,就是典型的遞歸下降和算符優先算法相結合的實現方式。只要了解這些編譯器的經典算法原理,C4的實現邏輯理解起來,還是比較輕松的。

讀懂這4個函數,528行代碼,你也可以實現一個C語言編譯器-8.jpg (39.14 KB, 下載次數: 0)

2020-7-17 12:33 上傳

此外,C4為了追求以最少的代碼實現自舉,在實現上采用了一些技巧。

比如,我們前面提到,C4不支持struct類型。這也意味著C4的源碼中不能使用struct類型。為此,它選擇使用數組來模擬struct結構。這樣乍看起來,可能會產生一些困惑。

個人認為,C4的一個槽點,就是它變量的命名上,過于簡潔。比如標記字節碼的位置的變量用e表示,其實如果用emit的話,就會清晰許多,也會更容易理解。

C4的衍生實現

除了C4的原生實現外,網上也有很多基于C4的衍生實現。

比如有人給C4額外增加了80多行代碼,卻給C4添加了JIT功能,使得執行速度得到明顯提升。

也有人對C4做了簡單修改,使得它可以直接產生真實的機器碼,并最終生成ELF可執行文件。

這些都是非常有趣的項目,都很值得研究。

C4的項目地址

在github上,找到用戶名為rswier的大牛,就可以看到C4的項目了。

讀懂這4個函數,528行代碼,你也可以實現一個C語言編譯器-9.jpg (10.81 KB, 下載次數: 0)

2020-7-17 12:33 上傳

結語

現代的編譯器項目,如GCC和Clang/LLVM,它們實現邏輯非常復雜,代碼規模巨大,一個人幾乎不可能完全搞清楚。即便是網上備受推崇的精簡實現TCC和LCC,它們的實現也相對比較復雜的,作為一個新手來說,也很難徹底研究清楚。

而C4的實現,只有四個函數,500多行源碼,個人認為是非常適合新手研究的一個項目。當然了,研究之前,最好具備一些編譯器的基礎知識,那樣理解起來就會比較容易了。

讀懂這4個函數,528行代碼,你也可以實現一個C語言編譯器-10.jpg (50.57 KB, 下載次數: 0)

2020-7-17 12:33 上傳

本文只介紹了C4編譯器項目的一些背景知識,并沒有對C4的實現做過多探討。感興趣的朋友可以到github上面找到它,仔細研究一下,相信你會有不少收獲!

如果對C4的代碼實現感興趣,或者有疑問的話,歡迎留言討論!感興趣的朋友多的話,我可以考慮更新幾篇文章,詳細講解一下C4的代碼實現。

原創不易,覺得有用的話,別忘了點贊!謝謝!

對編譯器、OS內核、性能調優、虛擬化等技術感興趣的童鞋,歡迎右上角關注!

版權聲明:未經允許,禁止轉載。文中部分圖片來源網絡,如有侵權,請通知刪除!

總結

以上是生活随笔為你收集整理的c语言编译器好玩的代码,读懂这4个函数,528行代码,你也可以实现一个C语言编译器...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。