简单的c编译器
实验要求:
语言特性:
1 数据类型:int,char
2 语句:赋值(=),if,while,for
3 算术运算:+,-,*,/,%,++,--,&,|,^,~,<<,>>
4 关系运算:==,>,<,>=,<=,!=
5 逻辑运算:&&(与),||(或),!(非)
6 复合语句:{、}括起来的语句
7 注释语句
8 简单的输入输出
流程:
语法分析
利用yacc进行语法分析,输出结果是语法树(包括了类型检查部分)
并且进行类型检查:
int char不能相互运算
变量重复定义
变量未定义
if while for中需要的bool型
得到语法树后的代码生成部分:
1 每一次运算都需要一个临时变量,用ti来表示
*2 对于运算表达式要后序遍历来计算,但是整个程序是先序遍历执行的
*3 if(else) while for 中程序要合理分段进行跳转
4 int和char的输入输出分别用data和data1
lex和yacc代码: mylexer 和 myparser,结合func 实现语法分析器。
代码生成部分的代码在codeGeneration.h和.cpp中,输入输出文件是file.txt和out.txt。具体项目在http://download.csdn.net/detail/kopm1/9737329
示例输入:
int main()
{
int i, j, n, r, x, y, pi = 0; char k='a';
print(1+2-3*4/5%6&7|8^9>>1);
for (i = 0; i < 10; i = i + 1)
print(k++ - 'a');
input(n);
while (n >= 0) {
if (n >= 10 && n < 100)
print(1);
else if (n <= -1 || n > 4) r = 0;
else {
for (r = 1; n > 0; n--)
r = (r << 3) + (r << 1);
}
//should not write r * 10 by this way in practice.
pi = 0;
for (i = -r; i < r; i = i + 1) {
for (j = -r; j < r; j = j + 1) {
x = (i * 2) + 1; y = (j * 2) + 1;
if (x * x + y * y < 4 * r * r) pi = pi + 1;
}
}
if (r >= 1){
if (r >= 2) print(pi / r);
else print(3);
}
input(n);
}
}
示例输出:
.386
.model flat, stdcall
option casemap : none
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\msvcrt.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\msvcrt.lib
includelib \masm32\lib\kernel32.lib
.data
k dd 0
pi dd 0
y dd 0
x dd 0
r dd 0
n dd 0
j dd 0
i dd 0
_t0 dd 0
_t1 dd 0
_t2 dd 0
_t3 dd 0
_t4 dd 0
_t5 dd 0
_t6 dd 0
_t7 dd 0
_t8 dd 0
_t9 dd 0
_t10 dd 0
_t11 dd 0
_t12 dd 0
_t13 dd 0
_t14 dd 0
_t15 dd 0
_t16 dd 0
_t17 dd 0
_t18 dd 0
_t19 dd 0
_t20 dd 0
_t21 dd 0
_t22 dd 0
_t23 dd 0
_t24 dd 0
_t25 dd 0
_t26 dd 0
_t27 dd 0
_t28 dd 0
data db '%d',0
data1 db '%c',0
.code
start:
mov eax, 0
mov pi,eax
mov eax, 97
mov k,eax
mov eax, 1
add eax, 2
mov _t0, eax
mov eax, 3
mov ebx, 4
mul ebx
mov _t1, eax
mov eax, _t1
mov ebx, 5
mov edx, 0
div ebx
mov _t2, eax
mov edx, 0
mov eax, _t2
mov ebx, 6
div ebx
mov _t3, edx
mov eax, _t0
sub eax, _t3
mov _t4, eax
mov eax, _t4
mov ebx, 7
and eax,ebx
mov _t5, eax
mov eax, _t5
mov ebx, 8
or eax,ebx
mov _t6, eax
mov eax, 9
sar eax, 1
mov _t7, eax
mov eax, _t6
mov ebx, _t7
xor eax,ebx
mov _t8, eax
invoke crt_printf,addr data, _t8
mov eax, 0
mov i,eax
@0:
mov eax, i
mov ecx, eax
mov eax, 10
mov ebx, eax
cmp ecx,ebx
jl @1
jmp @2
@1:
mov eax, k
sub eax, 97
mov _t9, eax
invoke crt_printf,addr data, _t9
mov eax, k
add eax, 1
mov k, eax
mov eax, i
add eax, 1
mov _t10, eax
mov eax, _t10
mov i,eax
jmp @0
@2:
invoke crt_scanf,addr data,addr n
@3:
mov eax, n
mov ecx, eax
mov eax, 0
mov ebx, eax
cmp ecx,ebx
jge @4
jmp @5
@4:
@6:
mov eax, n
mov ecx, eax
mov eax, 10
mov ebx, eax
cmp ecx,ebx
jge @7
jmp @9
@7:
mov eax, n
mov ecx, eax
mov eax, 100
mov ebx, eax
cmp ecx,ebx
jl @8
jmp @9
@8:
invoke crt_printf,addr data, 1
jmp @10
@9:
@11:
mov eax, n
mov ecx, eax
mov eax, 1
mov ebx, -1
mul ebx
mov ebx, eax
cmp ecx,ebx
jle @13
jmp @12
@12:
mov eax, n
mov ecx, eax
mov eax, 4
mov ebx, eax
cmp ecx,ebx
jg @13
jmp @14
@13:
mov eax, 0
mov r,eax
jmp @15
@14:
mov eax, 1
mov r,eax
@16:
mov eax, n
mov ecx, eax
mov eax, 0
mov ebx, eax
cmp ecx,ebx
jg @17
jmp @18
@17:
mov eax, r
sal eax, 3
mov _t11, eax
mov eax, r
sal eax, 1
mov _t12, eax
mov eax, _t11
add eax, _t12
mov _t13, eax
mov eax, _t13
mov r,eax
mov eax, n
sub eax, 1
mov n, eax
jmp @16
@18:
@15:
@10:
mov eax, 0
mov pi,eax
mov eax, r
mov ebx, -1
mul ebx
mov i,eax
@19:
mov eax, i
mov ecx, eax
mov eax, r
mov ebx, eax
cmp ecx,ebx
jl @20
jmp @21
@20:
mov eax, r
mov ebx, -1
mul ebx
mov j,eax
@22:
mov eax, j
mov ecx, eax
mov eax, r
mov ebx, eax
cmp ecx,ebx
jl @23
jmp @24
@23:
mov eax, i
mov ebx, 2
mul ebx
mov _t14, eax
mov eax, _t14
add eax, 1
mov _t15, eax
mov eax, _t15
mov x,eax
mov eax, j
mov ebx, 2
mul ebx
mov _t16, eax
mov eax, _t16
add eax, 1
mov _t17, eax
mov eax, _t17
mov y,eax
@25:
mov eax, x
mov ebx, x
mul ebx
mov _t18, eax
mov eax, y
mov ebx, y
mul ebx
mov _t19, eax
mov eax, _t18
add eax, _t19
mov _t20, eax
mov eax, 4
mov ebx, r
mul ebx
mov _t21, eax
mov eax, _t21
mov ebx, r
mul ebx
mov _t22, eax
mov eax, _t20
mov ecx, eax
mov eax, _t22
mov ebx, eax
cmp ecx,ebx
jl @26
jmp @27
@26:
mov eax, pi
add eax, 1
mov _t23, eax
mov eax, _t23
mov pi,eax
@27:
mov eax, j
add eax, 1
mov _t24, eax
mov eax, _t24
mov j,eax
jmp @22
@24:
mov eax, i
add eax, 1
mov _t25, eax
mov eax, _t25
mov i,eax
jmp @19
@21:
@28:
mov eax, r
mov ecx, eax
mov eax, 1
mov ebx, eax
cmp ecx,ebx
jge @29
jmp @30
@29:
@31:
mov eax, r
mov ecx, eax
mov eax, 2
mov ebx, eax
cmp ecx,ebx
jge @32
jmp @33
@32:
mov eax, pi
mov ebx, r
mov edx, 0
div ebx
mov _t26, eax
invoke crt_printf,addr data, _t26
jmp @34
@33:
invoke crt_printf,addr data, 3
@34:
@30:
invoke crt_scanf,addr data,addr n
jmp @3
@5:
invoke crt__getch
ret
end start