參考 Abdulaziz Ghuloum 論文《一種構造編譯器的捷徑》:先做最小可用編譯器,再逐步擴展。不必一次性構建完整前端,從能編譯 int main(){return 2;} 開始。
用 Flex 定義 Token:
"{" return '{';
"}" return '}';
"(" return '(';
")" return ')';
";" return ';';
[0-9]+ return NUMBER;
"return" return RETURN;
"int" return TYPE;
"main" return IDENTIFIER;
用 Bison 定義極簡文法:
function: TYPE IDENTIFIER '(' ')' '{' expression '}';
expression: RETURN NUMBER ';';
輸出 x86 32 位彙編:
.text
.global _start
_start:
movl $2, %ebx # 返回值
movl $1, %eax # sys_exit
int $0x80 # 系統調用
# 編譯器生成 out.s
./babyc return_two.c
# 彙編鏈接
as out.s -o out.o --32
ld -m elf_i386 -s -o out out.o
# 運行
./out
echo $? # 輸出 2
return 3;;return ~1;;