ZCC是一个用C++写的C99的编译器。
原2017年本科《编译原理》免考课设。
CMake >= 3.16
C++ 20
cd zcc
mkdir build && cd build
cmake ..
cmake --build .
Options:
-P only preprocessed
-E print preprocessed source code
-o filename Output to the specified file
-h help
-V use virtual machine to run the program.
-D Debug(virtual machine mode)
-A Print all data
Debug:
n next, print next assembly instruction and register data.
x <addr> print the data of the address.
q exit
Output:
.q 四元式文件
.s AT&T汇编
.st 输出的符号表文件
.ts 输出的Token序列文件
当前zcc使用的不是标准头文件,所以想要使用头文件,把头文件放到以下位置:
# Windows:
D:/zcc/include/
C:/zcc/include/
# Linux:
/usr/include/zcc/
#include
#define
#undef
#if
#ifndef
#ifdef
#elif
#else
#endif
string
INTEGER:
char, short, int, long
FLOAT:
float, double
OTHERS:
array
enum
struct
使用typedef定义的struct类型
+ - * / %
+= -= *= /= %=
< > >= <= == !=
|| && >> << ~ ^ | &
++ -- . [] ? : ->
sizeof
!
支持基本变量作为参数时函数重载
if () {} else{ }
while() {}
do {} while ()
for (;;) {}
break
continue
return
goto
switch() { case: break; default: }
默认模式下,会自动生成AT&T
汇编代码,并调用gcc
汇编得到可执行文件
Virtual-Machine
模式下,生成汇编代码,不调用gcc
,而是在虚拟机中运行
函数必须return
- 碍于寄存器分配不完善,多使用中间变量,防止寄存器溢出。
- 只支持生成32位汇编代码。
- 打开函数重载后,无法使用函数调用做函数的参数,暂时无法获取作为参数的函数的信息;
d=max(sum(a,b), max(c,b));
这样的也不行,执行顺序为sum -> max ->max
,最后调用max的时候,寄存器的值已经被调用前两个的时候修改了;指针运算除了前置自增自减,别的不行;bool
表达式溢出的问题,准别后面使用AST做的时候解决这个问题;(回填算法解决)- 浮点比较有整数,报浮点数据错误;
- 一个表达式中使用多次多维数组,寄存器溢出问题;
##
粘贴后的内容不一定为字符串,需要重新解析。y--
的减运算的位置会有错误,比如在跳转中。重定义宏时不会覆盖。- 数组做参数,并没有作为指针传值。
- 不支持结构体做函数参数。
- 比较运算没有中间变量保存结果,所以比较运算不能作为操作数参与运算。
- 逻辑运算两侧必须是比较运算,不能出现单独的操作数,例如:
a && b
类似的运算。 - 不能进行
a ^= b ^= a ^= b
类似的连续运算。 - 在Linux上运行经常出现未查明BUG。