一个c的编译器, 基本代码来自参考里面的代码,修复部分bug,还有加上中文注释😄
基本实现了c的所有语法,应该说是c的一个子集,而且能够自举(自己编译自己)
这个编译器目前只支持linux(有时间看看能不能跑在macos)
linux平台 gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
make install
非linux平台
docker run -it -v $(pwd):/opt/tmp/ --rm -w /opt/tmp gcc make install
详细make命令,可以看Makefile
# ./mycc
Usage: ./mycc [-vcSTM] [-o outfile] file [file ...]
-v give verbose output of the compilation stages
-c generate object files but don't link them
-S generate assembly files but don't link them
-T dump the AST trees for each input file
-M dump the symbol table for each input file
-o outfile, produce the outfile executable file
#include <stdio.h>
#include <stdlib.h>
struct a{
union {
int b
} c; // 目前只支持嵌套一个struct/union声明,而且只能是第一个成员😭,或者在外面声明好,再到里面用吧😭
long k
};
struct a xx;
int kk=1;
void main(){
int* kkp=&kk;
*kkp=*kkp+1;
xx.c.b=1;
xx.c.b=xx.c.b+1;
struct a* sp=&xx;
sp->k=sp->k+2;
printf("hello world mycc! test output %d %d %d \n",*kkp,xx.c.b,sp->k);
}
编译
./mycc -o hello examples/helloworld.c # 编译
./hello # 执行
hello world mycc! test output 2 2 2 # 输出
# make clean quad
rm -f mycc mycc[0-9] *.o *.s out a.out incdir.h
echo "#define INCDIR \"/tmp/include\"" > incdir.h
cc -o mycc -g -Wall cg.c decl.c expr.c gen.c main.c misc.c opt.c scan.c stmt.c sym.c tree.c types.c
mkdir -p /tmp/include
cp -a include/. /tmp/include
cp mycc /tmp
chmod +x /tmp/mycc
./mycc -o mycc0 cg.c decl.c expr.c gen.c main.c misc.c opt.c scan.c stmt.c sym.c tree.c types.c
./mycc0 -o mycc1 cg.c decl.c expr.c gen.c main.c misc.c opt.c scan.c stmt.c sym.c tree.c types.c
./mycc1 -o mycc2 cg.c decl.c expr.c gen.c main.c misc.c opt.c scan.c stmt.c sym.c tree.c types.c
size mycc[012]
text data bss dec hex filename
97560 2972 48 100580 188e4 mycc0
97560 2972 48 100580 188e4 mycc1
97560 2972 48 100580 188e4 mycc2
可以看到自己编译自己的mycc0,mycc1,mycc2大小一致,证明成功
# make clean test
rm -f mycc mycc[0-9] *.o *.s out a.out incdir.h
echo "#define INCDIR \"/tmp/include\"" > incdir.h
cc -o mycc -g -Wall cg.c decl.c expr.c gen.c main.c misc.c opt.c scan.c stmt.c sym.c tree.c types.c
mkdir -p /tmp/include
cp -a include/. /tmp/include
cp mycc /tmp
chmod +x /tmp/mycc
(cd tests; chmod +x runtests; ./runtests)
input001.c: OK
input002.c: OK
input003.c: OK
# 省略
input149.c: OK
input150.c: OK
这个是gnu c 编译器编译出来的mycc的test case成功
# make clean test0
rm -f mycc mycc[0-9] *.o *.s out a.out incdir.h
echo "#define INCDIR \"/tmp/include\"" > incdir.h
cc -o mycc -g -Wall cg.c decl.c expr.c gen.c main.c misc.c opt.c scan.c stmt.c sym.c tree.c types.c
mkdir -p /tmp/include
cp -a include/. /tmp/include
cp mycc /tmp
chmod +x /tmp/mycc
./mycc -o mycc0 cg.c decl.c expr.c gen.c main.c misc.c opt.c scan.c stmt.c sym.c tree.c types.c
(cd tests; chmod +x runtests0; ./runtests0)
input001.c: OK
input002.c: OK
input003.c: OK
# 省略
input149.c: OK
input150.c: OK
这个是mycc编译器编译出来的mycc0的test case成功