回覆列表
-
1 # CM好看影片
-
2 # 大河電子發燒友之家
其實編譯器的原理一點都不復雜。就兩部分,scanner和parser,前者附則tokenization後者負責parsing。
難點在於你怎樣設計你的語言。要想簡單,那就設計一個只能算加減乘除的計算機就是了。要想複雜...你去試著編譯一下scala...聽說官方編譯器編譯scala用了21步,我估計這應該是最複雜的編譯器了吧。
題目有點久了,現在才想起來答,主要還是因為暑假才找到空閒的時間,把我的C11編譯器寫完了。
這個編譯器,(GitHub - wgtdkp/wgtcc: a tiny C compiler in C++) 一方面是為了學習 C11, 一方面為了練習C++。
在約11k程式碼中實現了:
幾乎完整的C11語法解析(除去變長陣列);
語義與型別檢查(仿gcc的錯誤提示)
預處理器
x86-64彙編程式碼生成, 多謝
@RednaxelaFX
的回答暫存器分配問題? - 編譯器,把我從無休止的手動最佳化中拯救回來
精簡的x86-64 ABI
心形很流行嘛,wgtcc編譯的M大(
@Milo Yip
) 在 如何用C語言畫一個“心形”? - C(程式語言)回答裡的程式碼:
#include <stdio.h>
int main() {
for (float y = 1.5f; y > -1.5f; y -= 0.1f) {
for (float x = -1.5f; x < 1.5f; x += 0.05f) {
float a = x * x + y * y - 1;
putchar(a * a * a - x * x * y * y * y <= 0.0f ? "*" : " ");
} putchar("\n");
}
}
C11 中有一些非常實用或者好玩的新特性,如 compound literal. 一個典型的用途是當我們想獲得一個數據的另一種表示的時候, 我們可能會這麼做:
float f = 1.5;
int i = *(int*)&f;
然而gcc 在開 -O2 時會報 break strict-aliasing rules 的warning。 有了 compound literal, 我們可以這麼做:
#define CAST(s_t, d_t, sv) \
(union {s_t sv; d_t dv;}){sv}.dv
float f = 1.5;
int i = CAST(float, int, f);
而且這是一個模板呢~
C11 也支援在identifier 中使用unicode字元了,中文程式設計很exciting:
#de