-
Notifications
You must be signed in to change notification settings - Fork 140
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add myc, an interpreter for simple C
- Loading branch information
Showing
19 changed files
with
2,043 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
1.Directory: | ||
--- | ||
| | ||
|------src 源代码 | ||
| | ||
| | ||
|------doc 相关文档 | ||
| | ||
| | ||
|------readme.txt | ||
|
||
2. How to use | ||
(1) 在Linux平台上,进入src目录,执行make命令,即可得到myc编译器 | ||
make | ||
|
||
(2) 运算测试代码 | ||
|
||
./myc ./test.c | ||
|
||
3. 简单C编译器 | ||
(1). 实现栈式存储管理,支持函数的递归调用 | ||
(2). 支持函数参数的传递 | ||
(3). 实现if语句、while语句、赋值语句(尚未支持for语句) | ||
(4). 不要求局部变量都放在函数体的开始处声明,提供了局部变量声明的灵活性。 | ||
(5). 只支持int型(尚支持其他数据类型),不支持void,要求所有函数的返回值为int | ||
(6). 允许int型全局变量 | ||
(7). 为了简单起见,提供scanf和printf关键字来支持输入输出,如 | ||
int a,b ; | ||
scanf(a,b); //从键盘接受一个输入 | ||
printf(a+1,b); //输出a+1和b的值 | ||
(8). 尚未支持指针 | ||
(9). 要求程序提供int型的main函数 | ||
(10). 2007年写的旧代码. 采用的是先编译后解释的思想,自定义了类似X86的汇编形式的中间代码 | ||
然后在虚拟机上解释执行。 | ||
(11). 采用的是基于语法图的自顶向下的分析方法。 | ||
expression.cpp实现了表达式的翻译 | ||
program_body.cpp实现了整个程序体的翻译 | ||
statement.cpp实现了语句的翻译 | ||
function_body.cpp实现了函数体的翻译 | ||
var_declare.cpp实现了变量声明的翻译 | ||
param_declare.cpp实现了函数参数声明的翻译 | ||
sym_table.cpp实现了符号表的管理 | ||
lex.cpp实现了词法分析器 | ||
c.cpp是主程序 | ||
virtual_machine.cpp实现了虚拟机 | ||
c.h为头文件 | ||
(12). 简单C编译器采用的是Wirth先生的PL/0(简化后的Pascal语言编译器)的框架. | ||
|
||
|
||
sheisc@163.com | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
0: SetBx 1 0 0 | ||
1: Jmp 0 0 32 | ||
2: Init 4 1 0 | ||
3: Jeq 3 4 8 | ||
4: Jmp 0 0 5 | ||
5: Init 4 2 0 | ||
6: Jeq 3 4 8 | ||
7: Jmp 0 0 12 | ||
8: Init 4 1 0 | ||
9: Mov 2 4 0 | ||
10: Ret 0 0 0 | ||
11: Jmp 0 0 31 | ||
12: Init 9 1 0 | ||
13: Sub 3 9 9 | ||
14: Mov 8 9 0 | ||
15: Init 6 19 0 | ||
16: Init 5 5 0 | ||
17: AddBx 5 0 0 | ||
18: Call 2 0 0 | ||
19: Mov 4 7 0 | ||
20: Init 10 2 0 | ||
21: Sub 3 10 10 | ||
22: Mov 9 10 0 | ||
23: Init 7 27 0 | ||
24: Init 6 6 0 | ||
25: AddBx 6 0 0 | ||
26: Call 2 0 0 | ||
27: Mov 5 8 0 | ||
28: Add 4 5 4 | ||
29: Mov 2 4 0 | ||
30: Ret 0 0 0 | ||
31: Ret 0 0 0 | ||
32: Init 4 1 0 | ||
33: Mov 3 4 0 | ||
34: Init 4 20 0 | ||
35: Jlt 3 4 37 | ||
36: Jmp 0 0 48 | ||
37: Mov 8 3 0 | ||
38: Init 6 42 0 | ||
39: Init 5 5 0 | ||
40: AddBx 5 0 0 | ||
41: Call 2 0 0 | ||
42: Mov 4 7 0 | ||
43: Out 4 0 0 | ||
44: Init 4 1 0 | ||
45: Add 3 4 4 | ||
46: Mov 3 4 0 | ||
47: Jmp 0 0 34 | ||
48: Ret 0 0 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#COMPILE.cpp = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c | ||
CXX = g++ -Wno-write-strings | ||
OUTPUT_OPTION = -o $@ | ||
|
||
myc: expression.o program_body.o statement.o function_body.o var_declare.o \ | ||
param_declare.o sym_table.o virtual_machine.o lex.o c.o | ||
$(CXX) $^ -o myc | ||
%.o: %.c | ||
$(CXX) -c $(OUTPUT_OPTION) $< | ||
clean: | ||
rm -rf *.o myc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include "c.h" | ||
|
||
#define ZCW_DEBUG | ||
|
||
////////////////////////////////////////////////////////////////////// | ||
int errorCount = 0; | ||
int ds[DsSize]; //数据段 0号单元不用 | ||
Instruction cs[CsSize]; //代码段 | ||
int csIndex = 2; //代码段下标 1号预留给(最终会)跳转到main的指令 | ||
//0号单元用于存放初始"变址寄存器"的指令 | ||
//int dsIndex = 0; //数据段下标 | ||
FILE * infile; //输入文件 | ||
FILE * outfile; //输出文件 | ||
|
||
|
||
char * instrs[] = { | ||
"Jtrue", //为真则跳转 (InsJtrue, arg1, , dest) | ||
"Jfalse", //为假则跳转 (InsJfalse,arg1, , dest) | ||
"Jmp", //无条件跳转 (InsJmp, , , dest) | ||
"Mov", //数据复制 (InsMov, arg1, ,dest) | ||
"Init", //初始化某单元 (InsInit,arg1,num, ) | ||
"Add", //加法 (InsAdd, arg1,arg2,dest) | ||
"Sub", //减法 (InsSub, arg1,arg2,dest) | ||
"Mul", //乘法 (InsMul, arg1,arg2,dest) | ||
"Div", //除法 (InsDiv, arg1,arg2,dest) | ||
"Mod", //取余 | ||
"Nop", //空操作 (InsNop, , , ) | ||
"Jlt", //判断是否< (InsLt,arg1,arg2,result) | ||
"Jle", //判断是否<= (InsLe,arg1,arg2,result) | ||
"Jgt", //判断是否> (InsGt,arg1,arg2,result) | ||
"Jge", //判断是否>= | ||
"Jeq", //判断是否== | ||
"Jne", //判断是否!= | ||
"Or", //逻辑或运算 | ||
"And", //逻辑与运算 | ||
"Not", //逻辑非运算 | ||
"In", //输入 | ||
"Out", //输出 | ||
"Uminus", //求相反数 | ||
"Call", //过程调用 (InsCall,des, , ,); | ||
"Ret", //过程返回 (InsRet,expr, , ); | ||
"SetBx", //设置bx指针,指向活动记录首地址(InsSetBx,addr, , ) | ||
"AddBx", //增加bx的值 | ||
}; | ||
////////////////////////////////////////////////////////////////////////// | ||
|
||
void printCsInfo(){ | ||
for(int i = 0; i < csIndex; i++){ | ||
/* | ||
printf("%s %d %d %d\n", | ||
instrs[cs[i].optr],cs[i].arg1,cs[i].arg2,cs[i].result); | ||
*/ | ||
fprintf(outfile,"%d:\t %s %d %d %d\n", | ||
i,instrs[cs[i].optr],cs[i].arg1,cs[i].arg2,cs[i].result); | ||
} | ||
} | ||
|
||
|
||
|
||
/** | ||
* 产生一条四元式指令 | ||
*/ | ||
void gen(int instrType, int arg1,int arg2,int result){ | ||
if(csIndex >= CsSize){ | ||
printf("Code Segment overflows."); | ||
exit(1); | ||
} | ||
// | ||
cs[csIndex].optr = instrType; | ||
cs[csIndex].arg1 = arg1; | ||
cs[csIndex].arg2 = arg2; | ||
cs[csIndex].result = result; | ||
csIndex++; | ||
} | ||
/** | ||
* 语法错误处理 | ||
*/ | ||
void syntaxError(char * info){ | ||
errorCount++; | ||
printf("line %d : %s\n",lineNumber,info); | ||
//naive error recovery strategy,but simple :) | ||
//added by zcw, 2010.2.25 | ||
exit(1); | ||
} | ||
|
||
/** | ||
* main函数 | ||
*/ | ||
int main(int argc,char * args[]){ | ||
|
||
if(argc >= 2){ | ||
if((infile = fopen(args[1],"r")) == NULL){ | ||
printf("can't open file %s .\n",args[1]); | ||
exit(1); | ||
} | ||
else{ | ||
char name[80]; | ||
strcpy(name,args[1]); | ||
char * dot = strchr(name,'.'); | ||
if(dot == NULL){ | ||
strcat(name,".s"); | ||
} | ||
else{ | ||
strcpy(dot,".s"); | ||
} | ||
if( (outfile = fopen(name,"w")) == NULL){ | ||
fclose(infile); | ||
printf("can't not create file %s.\n",name); | ||
exit(1); | ||
} | ||
} | ||
} | ||
else{ | ||
printf("parameter specifying input file needed.\n"); | ||
exit(1); | ||
} | ||
getToken(); | ||
programBody(); | ||
if(token != EOF){ | ||
syntaxError("EOF needed."); | ||
} | ||
printCsInfo(); | ||
if(errorCount == 0) | ||
interpret(); | ||
else | ||
printf("there are %d errors in program.",errorCount); | ||
fclose(infile); | ||
fclose(outfile); | ||
printf("\n"); | ||
return 0; | ||
} |
Oops, something went wrong.