├── 说明文档-MiniC.pdf ├── 说明文档-Eeyore.pdf ├── 说明文档-Tigger.pdf ├── 说明文档-minic_riscv_汇编.pdf ├── compile ├── tigger_file ├── compile ├── eeyore_file │ ├── v0.lex │ ├── parse.h │ ├── v0.y │ └── parse.c ├── v1.lex ├── parse2tigger.h ├── v1.y └── parse2tigger.c ├── README.md ├── tigger2riscv.h ├── v2.lex ├── v2.y └── tigger2riscv.c /说明文档-MiniC.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoZHL/Simple_Compiler/HEAD/说明文档-MiniC.pdf -------------------------------------------------------------------------------- /说明文档-Eeyore.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoZHL/Simple_Compiler/HEAD/说明文档-Eeyore.pdf -------------------------------------------------------------------------------- /说明文档-Tigger.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoZHL/Simple_Compiler/HEAD/说明文档-Tigger.pdf -------------------------------------------------------------------------------- /说明文档-minic_riscv_汇编.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoZHL/Simple_Compiler/HEAD/说明文档-minic_riscv_汇编.pdf -------------------------------------------------------------------------------- /compile: -------------------------------------------------------------------------------- 1 | !#/bin/bash 2 | bison -yd v2.y 3 | flex v2.lex 4 | gcc y.tab.c lex.yy.c tigger2riscv.c -o riscv64 5 | cd tigger_file/ 6 | bash compile 7 | -------------------------------------------------------------------------------- /tigger_file/compile: -------------------------------------------------------------------------------- 1 | !#/bin/bash 2 | bison -yd ./eeyore_file/v0.y 3 | flex ./eeyore_file/v0.lex 4 | gcc y.tab.c lex.yy.c ./eeyore_file/parse.c -o ../eeyore 5 | bison -yd v1.y 6 | flex v1.lex 7 | gcc y.tab.c lex.yy.c parse2tigger.c -o ../tigger 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple_Compiler 2 | 这是一个简单的minic编译器,minic语法可以参见说明文档。 3 | 4 | 编译器中间经过了三次变化,第一次从minic转为eeyore三地址码,第二次从eeyore转为tigger(实质上是分配了寄存器),第三次从tigger转为riscv汇编语言。 5 | 6 | 第一个部分最为麻烦,需要将繁杂的minic语句转为三地址码,具体可以在最里层的文件夹查看;第二部分需要进行活性分析并分配寄存器,可以在中层的文件夹查看;第三次只用做简单的一对一翻译工作,没有什么难度,可以在最外层的文件夹查看。 7 | 8 | 要使用该编译器,可以直接运行最外层文件夹的compile文件,将会在最外层生成三个可执行文件(eeyore、tigger和riscv),实际使用时可以把三者连接起来直接将minic一步翻译到汇编;当然也可以分开使用获得中间代码。 9 | -------------------------------------------------------------------------------- /tigger2riscv.h: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/12/1 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #define true 1 13 | #define false 0 14 | //#define testing 15 | 16 | enum _expr_type 17 | { 18 | _func = 0, 19 | _decl = 1, 20 | _ope2 = 2, 21 | _ope1 = 3, 22 | _assi = 4, 23 | _ifbr = 5, 24 | _goto = 6, 25 | _plab = 7, 26 | _call = 8, 27 | _stor = 9, 28 | _load = 10, 29 | _ldad = 11, 30 | _retu = 12, 31 | _endf = 13, 32 | }; //to show what type the expression is 33 | 34 | typedef struct EXPRS 35 | { 36 | int index; 37 | enum _expr_type type; 38 | const char* op; 39 | const char* src1; 40 | const char* src2; 41 | const char* dst; 42 | }Expr; //the structure of expression 43 | 44 | static int exprIndex; 45 | 46 | void makeEXPR(enum _expr_type, const char*, const char*, const char*, const char*); 47 | void translate(); 48 | 49 | #define YYSTYPE const char* -------------------------------------------------------------------------------- /tigger_file/eeyore_file/v0.lex: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/11/3 5 | */ 6 | 7 | %{ 8 | #include "./eeyore_file/parse.h" 9 | #include "y.tab.h" 10 | 11 | %} 12 | 13 | integer [1-9][0-9]*|"0" 14 | letter [a-zA-Z] 15 | iden (_|{letter})(_|[0-9]|{letter})* 16 | space [ \t]+ 17 | enter [\n] 18 | comment "//"[^\n]* 19 | 20 | 21 | %% 22 | int {return TYPE;} 23 | {comment} {} 24 | {space} {} 25 | {enter} {_line_num++;} 26 | if {return IF;} 27 | else {return ELSE;} 28 | while {return WHILE;} 29 | return {return RETURN;} 30 | main {return MAIN;} 31 | {integer} {yylval = makeNode(strdup(yytext), NULL, _imme); return IMM;} 32 | {iden} {yylval = makeNode(strdup(yytext), NULL, _iden); return IDEN;} 33 | "+" {return ADD;} 34 | "-" {return SUB;} 35 | "*" {return MUL;} 36 | "/" {return DIV;} 37 | "%" {return MOD;} 38 | "=" {return ASG;} 39 | "!" {return NOT;} 40 | "<" {return LTH;} 41 | ">" {return GTH;} 42 | "&&" {return AND;} 43 | "||" {return OR;} 44 | "==" {return EQU;} 45 | "!=" {return NEQ;} 46 | "(" {return LBS;} 47 | ")" {return RBS;} 48 | "[" {return LBM;} 49 | "]" {return RBM;} 50 | "{" {return LBL;} 51 | "}" {return RBL;} 52 | "," {return COM;} 53 | ";" {return SEM;} 54 | 55 | %% 56 | 57 | 58 | 59 | int yywrap() 60 | { 61 | return 1; 62 | } 63 | -------------------------------------------------------------------------------- /tigger_file/v1.lex: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/12/1 5 | */ 6 | 7 | %{ 8 | #include "parse2tigger.h" 9 | #include "y.tab.h" 10 | 11 | %} 12 | 13 | integer [1-9][0-9]*|"0" 14 | letter [a-zA-Z] 15 | iden (_|{letter})(_|[0-9]|{letter})* 16 | space [ \t]+ 17 | enter [\n] 18 | comment "//"[^\n]* 19 | function f_{iden} 20 | variable (T|t|p){integer} 21 | label l{integer} 22 | 23 | 24 | %% 25 | {comment} {} 26 | {space} {} 27 | {enter} {} 28 | var {return VAR;} 29 | call {return CAL;} 30 | param {return PAR;} 31 | return {return RET;} 32 | end {return END;} 33 | if {return IFS;} 34 | goto {return GOT;} 35 | {variable} {yylval = strdup(yytext); return VARNAME;} 36 | {function} {yylval = strdup(yytext+2); return FUNCNAME;} 37 | {label} {yylval = strdup(yytext+1); return LABNAME;} 38 | {integer} {yylval = strdup(yytext); return IMMNAME;} 39 | "[" {return LMB;} 40 | "]" {return RMB;} 41 | "!" {return NOT;} 42 | "-" {return MIN;} 43 | "=" {return ASS;} 44 | "!=" {yylval = strdup(yytext); return OP2;} 45 | "==" {yylval = strdup(yytext); return OP2;} 46 | ">" {yylval = strdup(yytext); return OP2;} 47 | "<" {yylval = strdup(yytext); return OP2;} 48 | "&&" {yylval = strdup(yytext); return OP2;} 49 | "||" {yylval = strdup(yytext); return OP2;} 50 | "+" {yylval = strdup(yytext); return OP2;} 51 | "*" {yylval = strdup(yytext); return OP2;} 52 | "/" {yylval = strdup(yytext); return OP2;} 53 | "%" {yylval = strdup(yytext); return OP2;} 54 | ":" {return COL;} 55 | %% 56 | 57 | 58 | 59 | int yywrap() 60 | { 61 | return 1; 62 | } 63 | -------------------------------------------------------------------------------- /v2.lex: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/12/17 5 | */ 6 | 7 | %{ 8 | #include "tigger2riscv.h" 9 | #include "y.tab.h" 10 | 11 | %} 12 | 13 | integer [1-9][0-9]*|"0" 14 | letter [a-zA-Z] 15 | iden (_|{letter})(_|[0-9]|{letter})* 16 | space [ \t]+ 17 | enter [\n] 18 | comment "//"[^\n]* 19 | function f_{iden} 20 | register (v|s|t|a){integer} 21 | label l{integer} 22 | 23 | 24 | %% 25 | {comment} {} 26 | {space} {} 27 | {enter} {} 28 | store {return STORE;} 29 | call {return CALL;} 30 | malloc {return MALLOC;} 31 | end {return END;} 32 | if {return IF;} 33 | goto {return GOTO;} 34 | loadaddr {return LOADADDR;} 35 | load {return LOAD;} 36 | return {return RETURN;} 37 | {register} {yylval = strdup(yytext); return REGNAME;} 38 | {function} {yylval = strdup(yytext+2); return FUNCNAME;} 39 | {label} {yylval = strdup(yytext+1); return LABNAME;} 40 | {integer} {yylval = strdup(yytext); return IMMNAME;} 41 | "[" {return LMB;} 42 | "]" {return RMB;} 43 | "!" {return NOT;} 44 | "-" {return MIN;} 45 | "=" {return ASS;} 46 | "!=" {yylval = strdup(yytext); return OP2;} 47 | "==" {yylval = strdup(yytext); return OP2;} 48 | ">" {yylval = strdup(yytext); return OP2;} 49 | "<" {yylval = strdup(yytext); return OP2;} 50 | "&&" {yylval = strdup(yytext); return OP2;} 51 | "||" {yylval = strdup(yytext); return OP2;} 52 | "+" {yylval = strdup(yytext); return OP2;} 53 | "*" {yylval = strdup(yytext); return OP2;} 54 | "/" {yylval = strdup(yytext); return OP2;} 55 | "%" {yylval = strdup(yytext); return OP2;} 56 | ":" {return COL;} 57 | %% 58 | 59 | 60 | 61 | int yywrap() 62 | { 63 | return 1; 64 | } 65 | -------------------------------------------------------------------------------- /tigger_file/parse2tigger.h: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/12/1 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #define true 1 13 | #define false 0 14 | //#define testing 15 | 16 | enum _expr_type 17 | { 18 | _func = 0, 19 | _decl = 1, 20 | _ope2 = 2, 21 | _ope1 = 3, 22 | _assi = 4, 23 | _ifbr = 5, 24 | _goto = 6, 25 | _plab = 7, 26 | _para = 8, 27 | _call = 9, 28 | _retu = 10, 29 | _ends = 11, 30 | }; //to show what type the expression is 31 | 32 | typedef struct EXPRS 33 | { 34 | int index; 35 | enum _expr_type type; 36 | const char* op; 37 | const char* src1; 38 | const char* src2; 39 | const char* dst; 40 | }Expr; //the structure of expression 41 | 42 | typedef struct VARS 43 | { 44 | int index; 45 | const char* name; 46 | short global; 47 | short array; 48 | int size; 49 | const char* globalname; 50 | }Var; //the structure of variable 51 | 52 | typedef enum _result_type 53 | { 54 | _rfunc = 0, 55 | _rdecl = 1, 56 | _rope2 = 2, 57 | _rope1 = 3, 58 | _rassi = 4, 59 | _rifbr = 5, 60 | _rgoto = 6, 61 | _rplab = 7, 62 | _rcall = 8, 63 | _rstor = 9, 64 | _rload = 10, 65 | _rldad = 11, 66 | _rretu = 12, 67 | _rends = 13, 68 | }RTYPE; 69 | 70 | typedef struct RESULT 71 | { 72 | int index; 73 | RTYPE type; 74 | const char* op; 75 | const char* src1; 76 | const char* src2; 77 | const char* dst; 78 | }ResEntry; //the structure of result expression 79 | 80 | static int exprIndex; 81 | static int varIndex; 82 | static int resultIndex; 83 | static int globalIndex; 84 | 85 | void addVar(const char*, short, short, const char*); 86 | void makeEXPR(enum _expr_type, const char*, const char*, const char*, const char*); 87 | void updateTable(); 88 | void printResult(); 89 | void testExprList(); 90 | void testActtab(); 91 | 92 | #define YYSTYPE const char* -------------------------------------------------------------------------------- /tigger_file/eeyore_file/parse.h: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/11/3 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | enum _node_type 12 | { 13 | _resv = 0, //reserved node 14 | _vdcl = 1, //variable declare 15 | _fdcl = 2, //function declare 16 | _vdef = 3, //variable define 17 | _fdef = 4, //function define 18 | _main = 5, //main funciton 19 | _stat = 6, //statement 20 | _expr = 7, //expression 21 | _iden = 8, //identifier 22 | _imme = 9, //immediate number 23 | }; 24 | 25 | enum _var_type 26 | { 27 | _vari = 0, //variable 28 | _para = 1, //parameter 29 | _temp = 2, //temporary use 30 | _inst = 3, //immediate number 31 | }; 32 | 33 | struct NODES; 34 | typedef struct NODES 35 | { 36 | enum _node_type type; 37 | struct NODES* son; //left son 38 | struct NODES* sib; //right sibling 39 | const char* attr; //attribute 40 | int linenum; //line number 41 | }Node; 42 | 43 | typedef struct 44 | { 45 | enum _var_type type; 46 | char* oriName; //original variable name 47 | char* yoreName; //transferred variable name 48 | int isarray; //check if array 49 | int valid; //check if valid in this environment 50 | int linenum; //line number 51 | int arraysize; //size of array 52 | }Variable; 53 | 54 | struct PARAM; 55 | typedef struct PARAM 56 | { 57 | int isarray; //check if the parameter is array 58 | int arraysize; //size of array 59 | struct PARAM* next; //next parameter 60 | }parameter; 61 | 62 | typedef struct 63 | { 64 | char* funcName; //function name 65 | int linenum; //line number 66 | int declared; //check if declared 67 | parameter* first; //the first parameter 68 | }Func; 69 | 70 | 71 | Node* makeNode(const char*, Node*, enum _node_type); 72 | Node* rightMost(Node*); 73 | void scanTree(Node* root); 74 | void printTree(Node*); 75 | 76 | static int _line_num; 77 | 78 | #define YYSTYPE Node* 79 | -------------------------------------------------------------------------------- /v2.y: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/12/17 5 | */ 6 | 7 | %{ 8 | #include "tigger2riscv.h" 9 | #include 10 | #include 11 | #include 12 | int global; 13 | int yylex(); 14 | int yyerror(char*); 15 | %} 16 | %token MALLOC END IF GOTO CALL STORE LOAD LOADADDR RETURN 17 | %token REGNAME FUNCNAME LABNAME IMMNAME 18 | %token LMB RMB NOT MIN ASS OP2 COL 19 | 20 | %% 21 | Goal: 22 | Statement Goal {} 23 | | Statement {} 24 | ; 25 | Statement: 26 | FUNCNAME LMB IMMNAME RMB LMB IMMNAME RMB {makeEXPR(_func, $1, $3, $6, NULL);} 27 | | REGNAME ASS MALLOC IMMNAME {makeEXPR(_decl, $1, $4, NULL, NULL);} 28 | | REGNAME ASS REGNAME OP2 REGNAME {makeEXPR(_ope2, $4, $3, $5, $1);} 29 | | REGNAME ASS REGNAME MIN REGNAME {makeEXPR(_ope2, "-", $3, $5, $1);} 30 | | REGNAME ASS MIN REGNAME {makeEXPR(_ope1, "-", $4, NULL, $1);} 31 | | REGNAME ASS NOT REGNAME {makeEXPR(_ope1, "!", $4, NULL, $1);} 32 | | REGNAME ASS REGNAME {makeEXPR(_assi, $1, $3, NULL, NULL);} 33 | | REGNAME ASS IMMNAME {makeEXPR(_assi, $1, $3, NULL, NULL);} 34 | | REGNAME LMB IMMNAME RMB ASS REGNAME {makeEXPR(_assi, $1, $6, $3, NULL);} 35 | | REGNAME ASS REGNAME LMB IMMNAME RMB {makeEXPR(_assi, $1, $3, NULL, $5);} 36 | | IF REGNAME OP2 REGNAME GOTO LABNAME {makeEXPR(_ifbr, $3, $2, $4, $6);} 37 | | GOTO LABNAME {makeEXPR(_goto, $2, NULL, NULL, NULL);} 38 | | LABNAME COL {makeEXPR(_plab, $1, NULL, NULL, NULL);} 39 | | CALL FUNCNAME {makeEXPR(_call, $2, NULL, NULL, NULL);} 40 | | STORE REGNAME IMMNAME {makeEXPR(_stor, $2, $3, NULL, NULL);} 41 | | LOAD IMMNAME REGNAME {makeEXPR(_load, $2, $3, NULL, NULL);} 42 | | LOAD REGNAME REGNAME {makeEXPR(_load, $2, $3, NULL, NULL);} 43 | | LOADADDR IMMNAME REGNAME {makeEXPR(_ldad, $2, $3, NULL, NULL);} 44 | | LOADADDR REGNAME REGNAME {makeEXPR(_ldad, $2, $3, NULL, NULL);} 45 | | RETURN {makeEXPR(_retu, NULL, NULL, NULL, NULL);} 46 | | END FUNCNAME {makeEXPR(_endf, $2, NULL, NULL, NULL);} 47 | ; 48 | %% 49 | 50 | 51 | int main(int argc, char* argv[]) 52 | { 53 | 54 | #ifdef testing 55 | freopen("test.txt", "r", stdin); 56 | //freopen("out.txt", "w", stdout); 57 | //freopen("error.txt", "w", stderr); 58 | #endif 59 | #ifndef testing 60 | char buf[1024]; 61 | char ch; 62 | while(~scanf("%[^\n]", buf)) 63 | { 64 | fprintf(stderr, "%s\n", buf); 65 | scanf("%c", &ch); 66 | } 67 | rewind(stdin); 68 | #endif 69 | 70 | exprIndex = 0; 71 | yyparse(); 72 | 73 | translate(); 74 | 75 | return 0; 76 | } 77 | 78 | int yyerror(char* error) 79 | { 80 | fprintf(stderr, "Syntax error: %s\n", error); 81 | exit(1); 82 | } 83 | 84 | -------------------------------------------------------------------------------- /tigger_file/v1.y: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/12/1 5 | */ 6 | 7 | %{ 8 | #include "parse2tigger.h" 9 | #include 10 | #include 11 | #include 12 | int global; 13 | int yylex(); 14 | int yyerror(char*); 15 | %} 16 | %token VAR CAL PAR RET END IFS GOT LMB RMB NOT MIN ASS OP2 COL 17 | %token VARNAME FUNCNAME LABNAME IMMNAME 18 | 19 | %% 20 | Goal: 21 | Statement Goal {} 22 | | Statement {} 23 | ; 24 | Statement: 25 | FUNCNAME LMB IMMNAME RMB 26 | { 27 | makeEXPR(_func, $1, $3, NULL, NULL); 28 | global = false; 29 | } 30 | | VAR VARNAME 31 | { 32 | if(global == true) 33 | { 34 | addVar($2, true, false, NULL); 35 | makeEXPR(_decl, $2, "", NULL, NULL); 36 | } 37 | else 38 | { 39 | addVar($2, false, false, NULL); 40 | makeEXPR(_decl, $2, NULL, NULL, NULL); 41 | } 42 | } 43 | | VAR IMMNAME VARNAME 44 | { 45 | if(global == true) 46 | { 47 | addVar($3, true, true, $2); 48 | makeEXPR(_decl, $3, "", "", $2); 49 | } 50 | else 51 | { 52 | addVar($3, false, true, $2); 53 | makeEXPR(_decl, $3, NULL, "", $2); 54 | } 55 | } 56 | | VARNAME ASS RightValue OP2 RightValue {makeEXPR(_ope2, $4, $3, $5, $1);} 57 | | VARNAME ASS RightValue MIN RightValue {makeEXPR(_ope2, "-", $3, $5, $1);} 58 | | VARNAME ASS MIN RightValue {makeEXPR(_ope1, "-", $4, NULL, $1);} 59 | | VARNAME ASS NOT RightValue {makeEXPR(_ope1, "!", $4, NULL, $1);} 60 | | VARNAME ASS RightValue {makeEXPR(_assi, $3, $1, "0", NULL);} 61 | | VARNAME LMB RightValue RMB ASS RightValue {makeEXPR(_assi, $6, $1, "1", $3);} 62 | | VARNAME ASS VARNAME LMB RightValue RMB {makeEXPR(_assi, $3, $1, "2", $5);} 63 | | IFS RightValue OP2 RightValue GOT LABNAME {makeEXPR(_ifbr, $3, $2, $4, $6);} 64 | | GOT LABNAME {makeEXPR(_goto, $2, NULL, NULL, NULL);} 65 | | LABNAME COL {makeEXPR(_plab, $1, NULL, NULL, NULL);} 66 | | PAR RightValue {makeEXPR(_para, $2, NULL, NULL, NULL);} 67 | | CAL FUNCNAME {makeEXPR(_call, NULL, $2, NULL, NULL);} 68 | | VARNAME ASS CAL FUNCNAME {makeEXPR(_call, $1, $4, NULL, NULL);} 69 | | RET RightValue {makeEXPR(_retu, $2, NULL, NULL, NULL);} 70 | | END FUNCNAME {makeEXPR(_ends, $2, NULL, NULL, NULL); global = true;} 71 | ; 72 | RightValue: 73 | VARNAME {$$=$1;} 74 | | IMMNAME {$$=$1;} 75 | ; 76 | %% 77 | 78 | 79 | int main(int argc, char* argv[]) 80 | { 81 | global = true; 82 | #ifndef testing 83 | char buf[1024]; 84 | char ch; 85 | while(~scanf("%[^\n]", buf)) 86 | { 87 | fprintf(stderr, "%s\n", buf); 88 | scanf("%c", &ch); 89 | } 90 | rewind(stdin); 91 | #endif 92 | 93 | #ifdef testing 94 | freopen("test.txt", "r", stdin); 95 | freopen("out.txt", "w", stdout); 96 | //freopen("error.txt", "w", stderr); 97 | #endif 98 | 99 | exprIndex = 0; 100 | varIndex = 0; 101 | resultIndex = 0; 102 | globalIndex = 0; 103 | yyparse(); 104 | 105 | 106 | #ifdef testing 107 | //testExprList(); 108 | #endif 109 | 110 | updateTable(); 111 | 112 | #ifdef testing 113 | //fprintf(stdout, "update already\n"); 114 | //testActtab(); 115 | #endif 116 | 117 | printResult(); 118 | 119 | #ifdef testing 120 | //fprintf(stdout, "print result already\n"); 121 | fclose(stdin); 122 | fclose(stdout); 123 | #endif 124 | 125 | return 0; 126 | } 127 | 128 | int yyerror(char* error) 129 | { 130 | fprintf(stderr, "Syntax error: %s\n", error); 131 | exit(1); 132 | } 133 | 134 | -------------------------------------------------------------------------------- /tigger_file/eeyore_file/v0.y: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/11/3 5 | */ 6 | 7 | %{ 8 | #include "./eeyore_file/parse.h" 9 | #include 10 | #include 11 | #include 12 | static Node * root; 13 | int yylex(); 14 | int yyerror(char*); 15 | %} 16 | %token TYPE IF ELSE WHILE RETURN MAIN IMM IDEN ADD SUB MUL DIV MOD 17 | %token ASG NOT LTH GTH AND OR EQU NEQ LBS RBS LBM RBM LBL RBL COM SEM 18 | 19 | 20 | %% 21 | Root: 22 | Goal {$$=$1; root=$1;} 23 | Goal: 24 | VarDefn Goal {$$=$1; $$->sib=$2;} 25 | | FuncDefn Goal {$$=$1; $$->sib=$2;} 26 | | FuncDecl Goal {$$=$1; $$->sib=$2;} 27 | | MainFunc {$$=$1;} 28 | ; 29 | VarDefn: 30 | TYPE IDEN SEM {$$=makeNode("int;", $2, _vdef);} 31 | | TYPE IDEN LBM IMM RBM SEM {$$=makeNode("int[];", $2, _vdef); $2->sib=$4;} 32 | ; 33 | VarDecl: 34 | TYPE IDEN {$$=makeNode("int", $2, _vdcl);} 35 | | TYPE IDEN LBM RBM {$$=makeNode("int[]", $2, _vdcl);} 36 | | TYPE IDEN LBM IMM RBM {$$=makeNode("int[]", $2, _vdcl); $2->sib=$4;} 37 | ; 38 | ParamList: 39 | VarDecl {$$=$1;} 40 | | VarDecl COM ParamList {$$=$1; $$->sib=$3;} 41 | | {$$=NULL;} 42 | ; 43 | FuncDecl: 44 | TYPE IDEN LBS ParamList RBS SEM {$$=makeNode("func;", $2, _fdcl); $2->sib=$4;} 45 | ; 46 | FuncStat: 47 | FuncDecl FuncStat {$$=$1; $$->sib=$2;} 48 | | Statement FuncStat {$$=$1; $$->sib=$2;} 49 | | {$$=NULL;} 50 | ; 51 | FuncDefn: 52 | TYPE IDEN LBS ParamList RBS LBL FuncStat RBL 53 | { 54 | $$=makeNode("func", $2, _fdef); 55 | $2->sib=$4; 56 | rightMost($2)->sib=$7; 57 | } 58 | ; 59 | MainFunc: 60 | TYPE MAIN LBS RBS LBL FuncStat RBL {$$=makeNode("main", $6, _main);} 61 | ; 62 | IdenList: 63 | Expression {$$=$1;} 64 | | Expression COM IdenList {$$=$1; $$->sib=$3;} 65 | | {$$=NULL;} 66 | ; 67 | Statement: 68 | IF LBS Expression RBS Statement 69 | { 70 | $$=makeNode("if", $3, _stat); 71 | $3->sib=$5; 72 | } 73 | | IF LBS Expression RBS WithoutIF ELSE Statement 74 | { 75 | $$=makeNode("ifel", $3, _stat); 76 | $3->sib=$5; 77 | $5->sib=$7; 78 | } 79 | | WithoutIF {$$=$1;} 80 | Statements: 81 | Statement Statements {$$=$1; $$->sib=$2;} 82 | | {$$=NULL;} 83 | ; 84 | WithoutIF: 85 | LBL Statements RBL {$$=makeNode("{}", $2, _stat);} 86 | | WHILE LBS Expression RBS Statement 87 | { 88 | $$=makeNode("while", $3, _stat); 89 | $3->sib=$5; 90 | } 91 | | IDEN ASG Expression SEM {$$=makeNode("int=", $1, _stat); $1->sib=$3;} 92 | | IDEN LBM Expression RBM ASG Expression SEM 93 | { 94 | $$=makeNode("int[]=", $1, _stat); 95 | $1->sib=$3; 96 | $3->sib=$6; 97 | } 98 | | VarDefn {$$=$1;} 99 | | IDEN LBS IdenList RBS SEM {$$=makeNode("call", $1, _stat); $1->sib=$3;} 100 | | RETURN Expression SEM {$$=makeNode("return", $2, _stat);} 101 | ; 102 | Expression: 103 | Expression OR Expr1 {$$=makeNode("||", $1, _expr); $1->sib=$3;} 104 | | Expr1 {$$=$1;} 105 | ; 106 | Expr1: 107 | Expr1 AND Expr2 {$$=makeNode("&&", $1, _expr); $1->sib=$3;} 108 | | Expr2 {$$=$1;} 109 | ; 110 | Expr2: 111 | Expr2 EQU Expr3 {$$=makeNode("==", $1, _expr); $1->sib=$3;} 112 | | Expr2 NEQ Expr3 {$$=makeNode("!=", $1, _expr); $1->sib=$3;} 113 | | Expr3 {$$=$1;} 114 | ; 115 | Expr3: 116 | Expr3 LTH Expr4 {$$=makeNode("<", $1, _expr); $1->sib=$3;} 117 | | Expr3 GTH Expr4 {$$=makeNode(">", $1, _expr); $1->sib=$3;} 118 | | Expr4 {$$=$1;} 119 | ; 120 | Expr4: 121 | Expr4 ADD Expr5 {$$=makeNode("+", $1, _expr); $1->sib=$3;} 122 | | Expr4 SUB Expr5 {$$=makeNode("-", $1, _expr); $1->sib=$3;} 123 | | Expr5 {$$=$1;} 124 | ; 125 | Expr5: 126 | Expr5 MUL Expr6 {$$=makeNode("*", $1, _expr); $1->sib=$3;} 127 | | Expr5 DIV Expr6 {$$=makeNode("/", $1, _expr); $1->sib=$3;} 128 | | Expr5 MOD Expr6 {$$=makeNode("%", $1, _expr); $1->sib=$3;} 129 | | Expr6 {$$=$1;} 130 | ; 131 | Expr6: 132 | NOT Expr7 {$$=makeNode("not", $2, _expr);} 133 | | SUB Expr7 {$$=makeNode("neg", $2, _expr);} 134 | | Expr7 {$$=$1;} 135 | ; 136 | Expr7: 137 | IDEN LBM Expression RBM {$$=makeNode("[]", $1, _expr); $1->sib=$3;} 138 | | LBS Expression RBS {$$=$2;} 139 | | IDEN LBS IdenList RBS {$$=makeNode("call", $1, _expr); $1->sib=$3;} 140 | | IMM {$$=$1;} 141 | | IDEN {$$=$1;} 142 | ; 143 | %% 144 | 145 | 146 | int main(int argc, char* argv[]) 147 | { 148 | char buf[1024]; 149 | char ch; 150 | while(~scanf("%[^\n]", buf)) 151 | { 152 | fprintf(stderr, "%s\n", buf); 153 | scanf("%c", &ch); 154 | } 155 | rewind(stdin); 156 | _line_num=0; 157 | yyparse(); 158 | scanTree(root); 159 | return 0; 160 | } 161 | 162 | int yyerror(char* error) 163 | { 164 | fprintf(stderr, "Line %d: syntax error: %s\n", _line_num, error); 165 | exit(1); 166 | } 167 | -------------------------------------------------------------------------------- /tigger2riscv.c: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/12/17 5 | */ 6 | 7 | #include "tigger2riscv.h" 8 | #define EQ(a,b) (strcmp(a,b)==0) 9 | #define CPY(a, b, c) memcpy((void*)a, (const void*)b, (size_t)c) 10 | #define CMP(a, b, c) memcmp((const void*)a, (const void*)b, (unsigned int)c) 11 | 12 | Expr* ExprList[1000]; 13 | int stk = 0; 14 | void makeEXPR(enum _expr_type type, const char* op, const char* src1, const char* src2, const char* dst) 15 | { 16 | int i = exprIndex; 17 | ++exprIndex; 18 | ExprList[i] = (Expr*)malloc(sizeof(Expr)); 19 | ExprList[i]->index = i; 20 | ExprList[i]->type = type; 21 | ExprList[i]->op = op; 22 | ExprList[i]->src1 = src1; 23 | ExprList[i]->src2 = src2; 24 | ExprList[i]->dst = dst; 25 | return; 26 | } 27 | 28 | void printFunc(int index) 29 | { 30 | stk = (atoi(ExprList[index]->src2)/4+1)*16; 31 | //fprintf(stdout, " .size f,.-f\n"); 32 | fprintf(stdout, " .text\n"); 33 | fprintf(stdout, " .align 2\n"); 34 | fprintf(stdout, " .global %s\n", ExprList[index]->op); 35 | fprintf(stdout, " .type %s,@function\n", ExprList[index]->op); 36 | fprintf(stdout, "%s:\n", ExprList[index]->op); 37 | fprintf(stdout, " add sp,sp,-%d\n", stk); 38 | fprintf(stdout, " sw ra,%d(sp)\n", stk-4); 39 | return; 40 | } 41 | 42 | void printDecl(int index) 43 | { 44 | int size = atoi(ExprList[index]->src1); 45 | const char * name = ExprList[index]->op; 46 | fprintf(stdout, " .comm %s,%d,4\n", name, size*4); 47 | return; 48 | } 49 | 50 | void printOpe2(int index) 51 | { 52 | const char* op = ExprList[index]->op; 53 | const char* src1 = ExprList[index]->src1; 54 | const char* src2 = ExprList[index]->src2; 55 | const char* dst = ExprList[index]->dst; 56 | if(EQ(op,"+")) 57 | fprintf(stdout, " add %s,%s,%s\n", dst, src1, src2); 58 | else if(EQ(op,"-")) 59 | fprintf(stdout, " sub %s,%s,%s\n", dst, src1, src2); 60 | else if(EQ(op,"*")) 61 | fprintf(stdout, " mul %s,%s,%s\n", dst, src1, src2); 62 | else if(EQ(op,"/")) 63 | fprintf(stdout, " div %s,%s,%s\n", dst, src1, src2); 64 | else if(EQ(op,"%")) 65 | fprintf(stdout, " rem %s,%s,%s\n", dst, src1, src2); 66 | else if(EQ(op,"<")) 67 | fprintf(stdout, " slt %s,%s,%s\n", dst, src1, src2); 68 | else if(EQ(op,">")) 69 | fprintf(stdout, " sgt %s,%s,%s\n", dst, src1, src2); 70 | else if(EQ(op,"&&")) 71 | { 72 | fprintf(stdout, " and %s,%s,%s\n", dst, src1, src2); 73 | fprintf(stdout, " snez %s,%s\n", dst, dst); 74 | } 75 | else if(EQ(op,"||")) 76 | { 77 | fprintf(stdout, " or %s,%s,%s\n", dst, src1, src2); 78 | fprintf(stdout, " snez %s,%s\n", dst, dst); 79 | } 80 | else if(EQ(op,"!=")) 81 | { 82 | fprintf(stdout, " xor %s,%s,%s\n", dst, src1, src2); 83 | fprintf(stdout, " snez %s,%s\n", dst, dst); 84 | } 85 | else if(EQ(op,"==")) 86 | { 87 | fprintf(stdout, " xor %s,%s,%s\n", dst, src1, src2); 88 | fprintf(stdout, " seqz %s,%s\n", dst, dst); 89 | } 90 | return; 91 | } 92 | 93 | void printOpe1(int index) 94 | { 95 | const char* op = ExprList[index]->op; 96 | const char* src = ExprList[index]->src1; 97 | const char* dst = ExprList[index]->dst; 98 | if(EQ(op,"!")) 99 | fprintf(stdout, " seqz %s,%s\n", dst, src); 100 | else fprintf(stdout, " sub %s,x0,%s\n", dst, src); 101 | return; 102 | } 103 | 104 | void printAssi(int index) 105 | { 106 | const char* left = ExprList[index]->op; 107 | const char* right = ExprList[index]->src1; 108 | const char* larray = ExprList[index]->src2; 109 | const char* rarray = ExprList[index]->dst; 110 | if(rarray != NULL) 111 | fprintf(stdout, " lw %s,%s(%s)\n", left, rarray, right); 112 | else if(larray != NULL) 113 | fprintf(stdout, " sw %s,%s(%s)\n", right, larray, left); 114 | else if(left[0] == 'v') 115 | { 116 | fprintf(stdout, " .global %s\n", left); 117 | fprintf(stdout, " .section .sdata\n"); 118 | fprintf(stdout, " .align 2\n"); 119 | fprintf(stdout, " .type %s,@object\n", left); 120 | fprintf(stdout, " .size %s,4\n", left); 121 | fprintf(stdout, "%s:\n", left); 122 | fprintf(stdout, " .word 0\n"); 123 | } 124 | else if(isdigit(right[0])) 125 | fprintf(stdout, " li %s,%s\n", left, right); 126 | else fprintf(stdout, " mv %s,%s\n", left, right); 127 | return; 128 | } 129 | 130 | void printIfbr(int index) 131 | { 132 | const char* op = ExprList[index]->op; 133 | const char* src1 = ExprList[index]->src1; 134 | const char* src2 = ExprList[index]->src2; 135 | const char* label = ExprList[index]->dst; 136 | if(EQ(op,"!=")) 137 | fprintf(stdout, " bne"); 138 | else if(EQ(op,"==")) 139 | fprintf(stdout, " beq"); 140 | else if(EQ(op,"<")) 141 | fprintf(stdout, " blt"); 142 | else fprintf(stdout, " bgt"); 143 | fprintf(stdout, " %s,%s,.l%s\n", src1, src2, label); 144 | return; 145 | } 146 | 147 | void printGoto(int index) 148 | { 149 | fprintf(stdout, " j .l%s\n", ExprList[index]->op); 150 | return; 151 | } 152 | 153 | void printPlab(int index) 154 | { 155 | fprintf(stdout, ".l%s:\n", ExprList[index]->op); 156 | return; 157 | } 158 | 159 | void printCall(int index) 160 | { 161 | fprintf(stdout, " call %s\n", ExprList[index]->op); 162 | return; 163 | } 164 | 165 | void printStor(int index) 166 | { 167 | int var = atoi(ExprList[index]->src1); 168 | const char* reg = ExprList[index]->op; 169 | fprintf(stdout, " sw %s,%d(sp)\n", reg, var*4); 170 | return; 171 | } 172 | 173 | void printLoad(int index) 174 | { 175 | const char* var = ExprList[index]->op; 176 | const char* reg = ExprList[index]->src1; 177 | if(isdigit(var[0])) 178 | fprintf(stdout, " lw %s,%d(sp)\n", reg, atoi(var)*4); 179 | else 180 | { 181 | fprintf(stdout, " lui %s,%%hi(%s)\n", reg, var); 182 | fprintf(stdout, " lw %s,%%lo(%s)(%s)\n", reg, var, reg); 183 | } 184 | return; 185 | } 186 | 187 | void printLdad(int index) 188 | { 189 | const char* var = ExprList[index]->op; 190 | const char* reg = ExprList[index]->src1; 191 | if(isdigit(var[0])) 192 | fprintf(stdout, " add %s,sp,%d\n", reg, atoi(var)*4); 193 | else 194 | { 195 | fprintf(stdout, " lui %s,%%hi(%s)\n", reg, var); 196 | fprintf(stdout, " add %s,%s,%%lo(%s)\n", reg, reg, var); 197 | } 198 | return; 199 | } 200 | 201 | void printRetu(int index) 202 | { 203 | fprintf(stdout, " lw ra,%d(sp)\n", stk-4); 204 | fprintf(stdout, " add sp,sp,%d\n", stk); 205 | fprintf(stdout, " jr ra\n"); 206 | return; 207 | } 208 | 209 | void printEndf(int index) 210 | { 211 | fprintf(stdout, " .size %s,.-%s\n", ExprList[index]->op, ExprList[index]->op); 212 | return; 213 | } 214 | 215 | void translate() 216 | { 217 | int i = 0; 218 | for(; i < exprIndex; ++i) 219 | { 220 | switch(ExprList[i]->type) 221 | { 222 | case _func: printFunc(i); break; 223 | case _decl: printDecl(i); break; 224 | case _ope2: printOpe2(i); break; 225 | case _ope1: printOpe1(i); break; 226 | case _assi: printAssi(i); break; 227 | case _ifbr: printIfbr(i); break; 228 | case _goto: printGoto(i); break; 229 | case _plab: printPlab(i); break; 230 | case _call: printCall(i); break; 231 | case _stor: printStor(i); break; 232 | case _load: printLoad(i); break; 233 | case _ldad: printLdad(i); break; 234 | case _retu: printRetu(i); break; 235 | case _endf: printEndf(i); break; 236 | } 237 | } 238 | return; 239 | } 240 | -------------------------------------------------------------------------------- /tigger_file/eeyore_file/parse.c: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/11/3 5 | */ 6 | 7 | #include "parse.h" 8 | #define false 0 9 | #define true 1 10 | #define unknown 2 11 | #define EQ(a,b) (strcmp(a,b)==0) 12 | 13 | int VarCnt, TempCnt, ParamCnt; 14 | int LabelCnt, FuncCnt; 15 | Variable* VarList[2000]; 16 | Variable* ParamList[20]; 17 | Func* FuncList[1000]; 18 | int LayerMark[100]; 19 | int currLayer; 20 | int indent; 21 | 22 | void scanNode(Node* node); 23 | Variable* scanEXPR(Node* node); 24 | 25 | void initEnv() 26 | { 27 | VarCnt = TempCnt = ParamCnt = 0; 28 | LabelCnt = FuncCnt = 0; 29 | currLayer = indent = 0; 30 | LayerMark[0] = 0; 31 | } 32 | 33 | Node* makeNode(const char* attr, Node* son, enum _node_type type) 34 | { 35 | Node* newNode = (Node*)malloc(sizeof(Node)); 36 | newNode->type = type; 37 | newNode->son = son; 38 | newNode->sib = NULL; 39 | newNode->attr = attr; 40 | newNode->linenum = _line_num; 41 | return newNode; 42 | } 43 | 44 | Variable* makeVar(const char* oriName, int isarray, enum _var_type type, int linenum, int arraysize) 45 | { 46 | Variable* newVar = (Variable*)malloc(sizeof(Variable)); 47 | newVar->type = type; 48 | newVar->isarray = isarray; 49 | newVar->linenum = linenum; 50 | newVar->valid = true; 51 | newVar->oriName = (oriName==NULL?NULL:strdup(oriName)); 52 | newVar->arraysize = arraysize; 53 | if(type == _inst) 54 | { 55 | if(isarray || oriName==NULL) 56 | { 57 | fprintf(stderr, "Line %d: type error: %s\n", linenum, oriName); 58 | exit(1); 59 | } 60 | newVar->yoreName = strdup(oriName); 61 | return newVar; 62 | } 63 | else 64 | { 65 | char buffer[10] = {'\0'}; 66 | if(type == _vari) 67 | { 68 | sprintf(buffer, "T%d", VarCnt); 69 | VarList[VarCnt++] = newVar; 70 | } 71 | else if(type == _temp) sprintf(buffer, "t%d", TempCnt++); 72 | else 73 | { 74 | sprintf(buffer, "p%d", ParamCnt); 75 | ParamList[ParamCnt++] = newVar; 76 | } 77 | newVar->yoreName = strdup(buffer); 78 | if(type != _para) 79 | { 80 | if(indent) fprintf(stdout, " "); 81 | if(!isarray) fprintf(stdout, "var %s\n", newVar->yoreName); 82 | else fprintf(stdout, "var %d %s\n", 4*arraysize, newVar->yoreName); 83 | } 84 | return newVar; 85 | } 86 | } 87 | 88 | Variable* matchVar(const char* oriName, int isarray, enum _var_type type, int linenum) 89 | { 90 | if(type == _vari) 91 | { 92 | int i; 93 | for(i = 0; i < ParamCnt; ++i) 94 | if(EQ(ParamList[i]->oriName,oriName)) 95 | { 96 | if(isarray != unknown && isarray != ParamList[i]->isarray) 97 | { 98 | fprintf(stderr, "Line %d: type error: %s\n", linenum, oriName); 99 | exit(1); 100 | } 101 | return ParamList[i]; 102 | } 103 | for(i = VarCnt-1; i >= 0; --i) 104 | { 105 | if(EQ(VarList[i]->oriName,oriName) && VarList[i]->valid) 106 | { 107 | if(isarray != unknown && isarray != VarList[i]->isarray) 108 | { 109 | fprintf(stderr, "Line %d: type error: %s\n", linenum, oriName); 110 | exit(1); 111 | } 112 | return VarList[i]; 113 | } 114 | } 115 | fprintf(stderr, "Line %d: variable not defined: %s\n", linenum, oriName); 116 | exit(1); 117 | } 118 | else 119 | { 120 | fprintf(stderr, "Line %d: type error: %s\n", linenum, oriName); 121 | exit(1); 122 | } 123 | } 124 | 125 | 126 | void checkParameter(Node* node, parameter* param, const char* funcName, int undefined) 127 | { 128 | while(node && (undefined || param)) 129 | { 130 | Variable* temp = scanEXPR(node); 131 | if((!undefined) && temp->isarray != param->isarray) 132 | { 133 | fprintf(stderr, "Line %d: function parameter type error: %s(...)\n", 134 | node->linenum, funcName); 135 | exit(1); 136 | } 137 | if((!undefined) && (temp->isarray && param->arraysize && param->arraysize != temp->arraysize)) 138 | { 139 | fprintf(stderr, "Line %d: function parameter type error: %s(...)\n", 140 | node->linenum, funcName); 141 | exit(1); 142 | } 143 | if(indent) fprintf(stdout, " "); 144 | fprintf(stdout, "param %s\n", temp->yoreName); 145 | node = node->sib; 146 | if(!undefined) param = param->next; 147 | } 148 | if((!undefined) && (node && node->type == _vdcl) || param) 149 | { 150 | fprintf(stderr, "Line %d: function parameter more or less: %s\n", node->linenum, funcName); 151 | exit(1); 152 | } 153 | } 154 | 155 | Node* rightMost(Node* node) 156 | { 157 | while(node->sib) node = node->sib; 158 | return node; 159 | } 160 | 161 | Variable* scanEXPR(Node* node) 162 | { 163 | 164 | if(node->type == _imme) return makeVar(node->attr, false, _inst, node->linenum, 0); 165 | else if(node->type == _iden) return matchVar(node->attr, false, _vari, node->linenum); 166 | else 167 | { 168 | if(EQ(node->attr,"[]")) 169 | { 170 | Variable* id = matchVar(node->son->attr, true, _vari, node->linenum); 171 | Variable* expr = scanEXPR(node->son->sib); 172 | Variable* index = makeVar(NULL, false, _temp, node->linenum, 0); 173 | if(indent) fprintf(stdout, " "); 174 | fprintf(stdout, "%s = 4 * %s\n", index->yoreName, expr->yoreName); 175 | Variable* temp = makeVar(NULL, false, _temp, node->linenum, 0); 176 | if(indent) fprintf(stdout, " "); 177 | fprintf(stdout, "%s = %s [%s]\n", temp->yoreName, id->yoreName, index->yoreName); 178 | return temp; 179 | } 180 | else if(EQ(node->attr,"call")) 181 | { 182 | const char* funcName = node->son->attr; 183 | int i; 184 | for(i = 0; i < FuncCnt; ++i) 185 | if(EQ(funcName, FuncList[i]->funcName)) 186 | { 187 | checkParameter(node->son->sib, FuncList[i]->first, funcName, 0); 188 | Variable* temp = makeVar(NULL, false, _temp, node->linenum, 0); 189 | if(indent) fprintf(stdout, " "); 190 | fprintf(stdout, "%s = call f_%s\n", temp->yoreName, funcName); 191 | return temp; 192 | } 193 | fprintf(stderr, "Warning: Line %d: function not defined: %s\n", node->linenum, funcName); 194 | checkParameter(node->son->sib, NULL, funcName, 1); 195 | Variable* temp = makeVar(NULL, false, _temp, node->linenum, 0); 196 | if(indent) fprintf(stdout, " "); 197 | fprintf(stdout, "%s = call f_%s\n", temp->yoreName, funcName); 198 | return temp; 199 | } 200 | else 201 | { 202 | const char* op = node->attr; 203 | if(EQ(op, "neg") || EQ(op, "not")) 204 | { 205 | Variable* operand = scanEXPR(node->son); 206 | Variable* temp = makeVar(NULL, false, _temp, node->linenum, 0); 207 | if(indent) fprintf(stdout, " "); 208 | if(EQ(op, "neg")) fprintf(stdout, "%s = -%s\n", temp->yoreName, operand->yoreName); 209 | else fprintf(stdout, "%s = !%s\n", temp->yoreName, operand->yoreName); 210 | return temp; 211 | } 212 | else 213 | { 214 | Variable* operand1 = scanEXPR(node->son); 215 | Variable* operand2 = scanEXPR(node->son->sib); 216 | Variable* temp = makeVar(NULL, false, _temp, node->linenum, 0); 217 | 218 | char buffer[20] = {'\0'}; 219 | sprintf(buffer, "%s = %s %s %s", temp->yoreName, operand1->yoreName, op, operand2->yoreName); 220 | if(indent) fprintf(stdout, " "); 221 | fprintf(stdout, "%s\n", buffer); 222 | return temp; 223 | } 224 | } 225 | } 226 | } 227 | 228 | void scanSTAT(Node* node) 229 | { 230 | const char* op = node->attr; 231 | if(EQ(op,"if")) 232 | { 233 | int label = LabelCnt++; 234 | Variable* cond = scanEXPR(node->son); 235 | char buffer[30] = {'\0'}; 236 | sprintf(buffer, "if %s == 0 goto l%d\n", cond->yoreName, label); 237 | if(indent) fprintf(stdout, " "); 238 | fprintf(stdout, "%s\n", buffer); 239 | scanNode(node->son->sib); 240 | fprintf(stdout, "l%d:\n", label); 241 | return; 242 | } 243 | else if(EQ(op,"ifel")) 244 | { 245 | int label1 = LabelCnt++; 246 | int label2 = LabelCnt++; 247 | Variable* cond = scanEXPR(node->son); 248 | if(indent) fprintf(stdout, " "); 249 | fprintf(stdout, "if %s == 0 goto l%d\n", cond->yoreName, label1); 250 | scanNode(node->son->sib); 251 | if(indent) fprintf(stdout, " "); 252 | fprintf(stdout, "goto l%d\n", label2); 253 | fprintf(stdout, "l%d:\n", label1); 254 | scanNode(node->son->sib->sib); 255 | fprintf(stdout, "l%d:\n", label2); 256 | return; 257 | } 258 | else if(EQ(op,"{}")) 259 | { 260 | LayerMark[++currLayer] = VarCnt; 261 | node = node->son; 262 | while(node) 263 | { 264 | scanNode(node); 265 | node = node->sib; 266 | } 267 | int i; 268 | for(i = LayerMark[currLayer--]; i < VarCnt; ++i) 269 | VarList[i]->valid = false; 270 | return; 271 | } 272 | else if(EQ(op,"while")) 273 | { 274 | int label1 = LabelCnt++; 275 | int label2 = LabelCnt++; 276 | fprintf(stdout, "l%d:\n", label1); 277 | Variable* cond = scanEXPR(node->son); 278 | if(indent) fprintf(stdout, " "); 279 | fprintf(stdout, "if %s == 0 goto l%d\n", cond->yoreName, label2); 280 | scanNode(node->son->sib); 281 | if(indent) fprintf(stdout, " "); 282 | fprintf(stdout, "goto l%d\n", label1); 283 | fprintf(stdout, "l%d:\n", label2); 284 | return; 285 | } 286 | else if(EQ(op,"int=")) 287 | { 288 | Variable* operand = matchVar(node->son->attr, false, _vari, node->linenum); 289 | Variable* expr = scanEXPR(node->son->sib); 290 | if(indent) fprintf(stdout, " "); 291 | fprintf(stdout, "%s = %s\n", operand->yoreName, expr->yoreName); 292 | return; 293 | } 294 | else if(EQ(op,"int[]=")) 295 | { 296 | Variable* operand = matchVar(node->son->attr, true, _vari, node->son->linenum); 297 | Variable* index = scanEXPR(node->son->sib); 298 | Variable* index4 = makeVar(NULL, false, _temp, node->son->linenum, 0); 299 | if(indent) fprintf(stdout, " "); 300 | fprintf(stdout, "%s = 4 * %s\n", index4->yoreName, index->yoreName); 301 | Variable* expr = scanEXPR(node->son->sib->sib); 302 | if(indent) fprintf(stdout, " "); 303 | fprintf(stdout, "%s [%s] = %s\n", operand->yoreName, index4->yoreName, expr->yoreName); 304 | return; 305 | } 306 | else if(EQ(op,"call")) 307 | { 308 | const char* funcName = node->son->attr; 309 | int i; 310 | for(i = 0; i < FuncCnt; ++i) 311 | if(EQ(funcName, FuncList[i]->funcName)) 312 | { 313 | checkParameter(node->son->sib, FuncList[i]->first, funcName, 0); 314 | Variable* temp = makeVar(NULL, false, _temp, node->linenum, 0); 315 | if(indent) fprintf(stdout, " "); 316 | fprintf(stdout, "%s = call f_%s\n", temp->yoreName, funcName); 317 | return; 318 | } 319 | fprintf(stderr, "Warning: Line %d: function not defined: %s\n", node->linenum, funcName); 320 | checkParameter(node->son->sib, NULL, funcName, 1); 321 | Variable* temp = makeVar(NULL, false, _temp, node->linenum, 0); 322 | if(indent) fprintf(stdout, " "); 323 | fprintf(stdout, "%s = call f_%s\n", temp->yoreName, funcName); 324 | return; 325 | } 326 | else if(EQ(op,"return")) 327 | { 328 | Variable* expr = scanEXPR(node->son); 329 | if(indent) fprintf(stdout, " "); 330 | fprintf(stdout, "return %s\n", expr->yoreName); 331 | return; 332 | } 333 | } 334 | 335 | void scanVDEF(Node* node) 336 | { 337 | if(EQ(node->attr,"int;")) 338 | makeVar(node->son->attr, false, _vari, node->son->linenum, 0); 339 | else if(EQ(node->attr,"int[];")) 340 | { 341 | Variable* temp = makeVar(node->son->sib->attr, false, _inst, node->son->sib->linenum, 0); 342 | makeVar(node->son->attr, true, _vari, node->son->linenum, atoi(temp->yoreName)); 343 | } 344 | return; 345 | } 346 | 347 | Variable* scanVDCL(Node* node) 348 | { 349 | if(EQ(node->attr,"int")) return makeVar(node->son->attr, false, _para, node->linenum, 0); 350 | else 351 | { 352 | if(node->son->sib) return makeVar(node->son->attr, true, _para, node->linenum, atoi(node->son->sib->attr)); 353 | else return makeVar(node->son->attr, true, _para, node->linenum, 0); 354 | } 355 | } 356 | 357 | void addFunc(const char* funcName, Node* node, int declaring) 358 | { 359 | int declaredBefore = false; 360 | int index; 361 | int i; 362 | for(i = 0; i < FuncCnt; ++i) 363 | if(EQ(funcName,FuncList[i]->funcName)) 364 | { 365 | if(declaring || ((!declaring) && FuncList[i]->declared == false)) 366 | { 367 | fprintf(stderr, "Line %d: function redefine or redeclare: %s\n", node->linenum, funcName); 368 | exit(1); 369 | } 370 | declaredBefore = true; 371 | index = i; 372 | break; 373 | } 374 | 375 | if(!declaredBefore) 376 | { 377 | Func* newFunc = (Func*)malloc(sizeof(Func)); 378 | newFunc->funcName = strdup(funcName); 379 | newFunc->linenum = node->linenum; 380 | newFunc->declared = false; 381 | ParamCnt = 0; 382 | if(!(node->sib && node->sib->type == _vdcl)) 383 | newFunc->first = NULL; 384 | else 385 | { 386 | newFunc->first = (parameter*)malloc(sizeof(parameter)); 387 | node = node->sib; 388 | Variable* par = scanVDCL(node); 389 | parameter* tmp = newFunc->first; 390 | tmp->isarray = par->isarray; 391 | tmp->arraysize = par->arraysize; 392 | tmp->next = NULL; 393 | while(node->sib && node->sib->type == _vdcl) 394 | { 395 | tmp->next = (parameter*)malloc(sizeof(parameter)); 396 | tmp = tmp->next; 397 | node = node->sib; 398 | Variable* par = scanVDCL(node); 399 | tmp->isarray = par->isarray; 400 | tmp->arraysize = par->arraysize; 401 | tmp->next = NULL; 402 | } 403 | } 404 | FuncList[FuncCnt++] = newFunc; 405 | } 406 | else 407 | { 408 | parameter* ppointer = FuncList[index]->first; 409 | FuncList[index]->declared = false; 410 | while(node->sib && node->sib->type == _vdcl) 411 | { 412 | node = node->sib; 413 | Variable* par = scanVDCL(node); 414 | if(ppointer == NULL || ppointer->isarray != par->isarray || ppointer->arraysize != par->arraysize) 415 | { 416 | fprintf(stderr, "Line %d: function parameter type error: %s\n", node->linenum, funcName); 417 | exit(1); 418 | } 419 | ppointer = ppointer->next; 420 | } 421 | } 422 | return; 423 | } 424 | 425 | void scanFDEF(Node* node) 426 | { 427 | if(indent) 428 | { 429 | fprintf(stderr, "Line %d: form error\n", node->linenum); 430 | exit(1); 431 | } 432 | 433 | if(node->type == _main) 434 | { 435 | fprintf(stdout, "f_main [0]\n"); 436 | indent = true; 437 | node = node->son; 438 | 439 | while(node) 440 | { 441 | scanNode(node); 442 | node = node->sib; 443 | } 444 | 445 | indent = false; 446 | fprintf(stdout, "end f_main\n"); 447 | return; 448 | } 449 | 450 | node = node->son; 451 | 452 | const char* funcName = node->attr; 453 | addFunc(funcName, node, false); 454 | 455 | fprintf(stdout, "f_%s [%d]\n", funcName, ParamCnt); 456 | indent = true; 457 | 458 | while(node->sib && node->sib->type == _vdcl) node = node->sib; 459 | 460 | while(node->sib) 461 | { 462 | node = node->sib; 463 | scanNode(node); 464 | } 465 | 466 | indent = false; 467 | fprintf(stdout, "end f_%s\n", funcName); 468 | return; 469 | } 470 | 471 | void scanFDCL(Node* node) 472 | { 473 | node = node->son; 474 | if(indent) return; 475 | addFunc(node->attr, node, true); 476 | return; 477 | } 478 | 479 | void scanNode(Node* node) 480 | { 481 | switch(node->type) 482 | { 483 | case _vdcl: scanVDCL(node); break; 484 | case _fdcl: scanFDCL(node); break; 485 | case _vdef: scanVDEF(node); break; 486 | case _fdef: 487 | case _main: scanFDEF(node); break; 488 | case _stat: scanSTAT(node); break; 489 | case _expr: 490 | case _iden: 491 | case _imme: scanEXPR(node); break; 492 | default: 493 | fprintf(stderr, "Line %d: statement error: %s %d\n", node->linenum, node->attr, node->type); 494 | exit(1); 495 | } 496 | } 497 | 498 | void scanTree(Node* root) 499 | { 500 | initEnv(); 501 | while(root) 502 | { 503 | scanNode(root); 504 | root = root->sib; 505 | } 506 | } 507 | -------------------------------------------------------------------------------- /tigger_file/parse2tigger.c: -------------------------------------------------------------------------------- 1 | /* 2 | Programmer: Hugo Zhang 3 | Student ID: 1600012945 4 | Date: 2018/12/1 5 | */ 6 | 7 | #include "parse2tigger.h" 8 | #define EQ(a,b) (strcmp(a,b)==0) 9 | #define CPY(a, b, c) memcpy((void*)a, (const void*)b, (size_t)c) 10 | #define CMP(a, b, c) memcmp((const void*)a, (const void*)b, (unsigned int)c) 11 | 12 | Expr* ExprList[1000]; 13 | Var* VarList[100]; 14 | ResEntry* ResList[1000]; 15 | short actTab[1000][100]; 16 | int TvarIndex[100]; 17 | int tvarIndex[100]; 18 | int labelIndex[200]; 19 | int gotoIndex[200]; 20 | int regUsage[19]; //t first, s next, positive means var, -1 means imme, -2 means invalid 21 | int endtime[19]; 22 | int regIndex[100]; //positive means register, negative means stack, 20 means not valid 23 | int funcSaveReg[19]; 24 | 25 | 26 | void analyzeExpr(Expr* expr); 27 | 28 | void alterTab(int index, const char* src) 29 | { 30 | char temp = src[0]; 31 | if(temp == 'T') actTab[index][TvarIndex[atoi(src+1)]] = true; 32 | else if(temp == 't') actTab[index][tvarIndex[atoi(src+1)]] = true; 33 | return; 34 | } 35 | 36 | void alterTabF(int index, const char* src) 37 | { 38 | if(index < 0) return; 39 | char temp = src[0]; 40 | if(temp == 'T' && VarList[TvarIndex[atoi(src+1)]]->global==false) 41 | actTab[index][TvarIndex[atoi(src+1)]] = false; 42 | else if(temp == 't') actTab[index][tvarIndex[atoi(src+1)]] = false; 43 | return; 44 | } 45 | 46 | void analyzeDecl(Expr* expr) 47 | { 48 | CPY(actTab[expr->index], actTab[expr->index+1], sizeof(actTab[0])); 49 | int index = expr->index; 50 | char temp = (expr->op)[0]; 51 | if(temp == 'T') actTab[index][TvarIndex[atoi(expr->op+1)]] = false; 52 | else if(temp == 't') actTab[index][tvarIndex[atoi(expr->op+1)]] = false; 53 | return; 54 | } 55 | 56 | 57 | void analyzeOp(Expr* expr) 58 | { 59 | CPY(actTab[expr->index], actTab[expr->index+1], sizeof(actTab[0])); 60 | int index = expr->index; 61 | alterTabF(index-1, expr->dst); 62 | alterTab(index, expr->src1); 63 | if(expr->src2 == NULL) return; 64 | alterTab(index, expr->src2); 65 | return; 66 | } 67 | 68 | void analyzeAssign(Expr* expr) 69 | { 70 | CPY(actTab[expr->index], actTab[expr->index+1], sizeof(actTab[0])); 71 | int index = expr->index; 72 | alterTabF(index-1, expr->src1); 73 | alterTab(index, expr->op); 74 | if(expr->dst != NULL) alterTab(index, expr->dst); 75 | return; 76 | } 77 | 78 | void analyzeIf(Expr* expr) 79 | { 80 | CPY(actTab[expr->index], actTab[expr->index+1], sizeof(actTab[0])); 81 | int i; 82 | int num = labelIndex[atoi(expr->dst)]; 83 | for(i = 0; i < 100; ++i) 84 | if(actTab[num][i] == true) actTab[expr->index][i] = true; 85 | alterTab(expr->index, expr->src1); 86 | alterTab(expr->index, expr->src2); 87 | return; 88 | } 89 | 90 | void analyzeGoto(Expr* expr) 91 | { 92 | int num = atoi(expr->op); 93 | CPY(actTab[expr->index], actTab[labelIndex[num]], sizeof(actTab[0])); 94 | return; 95 | } 96 | 97 | void analyzeLabel(Expr* expr) 98 | { 99 | int num = atoi(expr->op); 100 | CPY(actTab[expr->index], actTab[expr->index+1], sizeof(actTab[0])); 101 | if(gotoIndex[num] < expr->index) return; 102 | while(CMP(actTab[gotoIndex[num]], actTab[expr->index], sizeof(actTab[0])) < 0) 103 | { 104 | int i = gotoIndex[num]; 105 | for(; i > expr->index; --i) 106 | analyzeExpr(ExprList[i]); 107 | CPY(actTab[expr->index], actTab[expr->index+1], sizeof(actTab[0])); 108 | } 109 | return; 110 | } 111 | 112 | void analyzeOne(Expr* expr) 113 | { 114 | if(expr->op == NULL) return; 115 | char temp = (expr->op)[0]; 116 | CPY(actTab[expr->index], actTab[expr->index+1], sizeof(actTab[0])); 117 | if(isdigit(temp)) return; 118 | int num = atoi(expr->op+1); 119 | if(expr->type == _para) alterTab(expr->index, expr->op); 120 | else alterTabF(expr->index-1, expr->op); 121 | return; 122 | } 123 | 124 | void analyzeRet(Expr* expr) 125 | { 126 | alterTab(expr->index, expr->op); 127 | return; 128 | } 129 | 130 | void analyzeExpr(Expr* expr) 131 | { 132 | switch(expr->type) 133 | { 134 | case _func: break; 135 | case _decl: analyzeDecl(expr); break; 136 | case _ope2: analyzeOp(expr); break; 137 | case _ope1: analyzeOp(expr); break; 138 | case _assi: analyzeAssign(expr); break; 139 | case _ifbr: analyzeIf(expr); break; 140 | case _goto: analyzeGoto(expr); break; 141 | case _plab: analyzeLabel(expr); break; 142 | case _para: analyzeOne(expr); break; 143 | case _call: analyzeOne(expr); break; 144 | case _retu: analyzeRet(expr); break; 145 | default: break; 146 | } 147 | return; 148 | } 149 | 150 | void addVar(const char* varName, short global, short array, const char* size) 151 | { 152 | int i = varIndex; 153 | ++varIndex; 154 | VarList[i] = (Var*)malloc(sizeof(Var)); 155 | VarList[i]->index = i; 156 | VarList[i]->name = varName; 157 | VarList[i]->global = global; 158 | VarList[i]->array = array; 159 | VarList[i]->size = (array?atoi(size):0); 160 | if(varName[0] == 'T') TvarIndex[atoi(varName+1)] = i; 161 | else tvarIndex[atoi(varName+1)] = i; 162 | return; 163 | } 164 | 165 | void makeEXPR(enum _expr_type type, const char* op, const char* src1, const char* src2, const char* dst) 166 | { 167 | int i = exprIndex; 168 | if(i != 0 && type == _ifbr && EQ(ExprList[i-1]->op,op) && EQ(ExprList[i-1]->src1,src1) 169 | && EQ(ExprList[i-1]->src2,src2) && EQ(ExprList[i-1]->dst,dst)) 170 | return; 171 | ++exprIndex; 172 | ExprList[i] = (Expr*)malloc(sizeof(Expr)); 173 | ExprList[i]->index = i; 174 | ExprList[i]->type = type; 175 | ExprList[i]->op = op; 176 | ExprList[i]->src1 = src1; 177 | ExprList[i]->src2 = src2; 178 | ExprList[i]->dst = dst; 179 | if(type == _plab) labelIndex[atoi(op)] = i; 180 | else if(type == _goto) gotoIndex[atoi(op)] = i; 181 | else if(type == _ifbr) gotoIndex[atoi(dst)] = i; 182 | return; 183 | } 184 | 185 | void updateTable() 186 | { 187 | memset(actTab, 0, sizeof(actTab)); 188 | int i; 189 | for(i = exprIndex-1; i >=0; --i) 190 | analyzeExpr(ExprList[i]); 191 | return; 192 | } 193 | 194 | void makeEntry(RTYPE type, int index, const char* op, const char* src1, const char* src2, const char* dst) 195 | { 196 | ResList[index] = (ResEntry*)malloc(sizeof(ResEntry)); 197 | ResList[index]->type = type; 198 | ResList[index]->index = index; 199 | ResList[index]->op = (op==NULL? NULL:strdup(op)); 200 | ResList[index]->src1 = (src1==NULL?NULL:strdup(src1)); 201 | ResList[index]->src2 = (src2==NULL?NULL:strdup(src2)); 202 | ResList[index]->dst = (dst==NULL?NULL:strdup(dst)); 203 | return; 204 | } 205 | 206 | const char* reg2string(int regnum) 207 | { 208 | char temp[5] = {0}; 209 | if(regnum <= 6) sprintf(temp, "t%d", regnum); 210 | else sprintf(temp, "s%d", regnum-7); 211 | return strdup(temp); 212 | } 213 | 214 | int string2reg(const char* regstring) 215 | { 216 | if(regstring[0] == 't') return atoi(regstring+1); 217 | else if(regstring[0] == 's') return (7+atoi(regstring+1)); 218 | else return -1; 219 | } 220 | 221 | int suitableReg(int * pstackSize, int contra1, int contra2) 222 | { 223 | int i = 0; 224 | int lastendind = -1; 225 | int lastendval = -1; 226 | for(i = 0; i < 19; ++i) 227 | { 228 | if(i == contra1 || i == contra2) continue; 229 | if(regUsage[i] < -1) 230 | { 231 | if(i > 6 && funcSaveReg[i] == -1) 232 | { 233 | int upd_i = resultIndex; 234 | ++resultIndex; 235 | char sta[5] = {0}; 236 | sprintf(sta, "%d", *pstackSize); 237 | makeEntry(_rstor, upd_i, reg2string(i), sta, NULL, NULL); 238 | funcSaveReg[i] = *pstackSize; 239 | ++(*pstackSize); 240 | } 241 | return i; 242 | } 243 | if(regUsage[i] > -1 && endtime[i] >= lastendval) 244 | { 245 | lastendval = endtime[i]; 246 | lastendind = i; 247 | } 248 | } 249 | 250 | const char* temp = reg2string(lastendind); 251 | char sta[5] = {0}; 252 | sprintf(sta, "%d", *pstackSize); 253 | regIndex[regUsage[lastendind]] = -(*pstackSize); 254 | ++(*pstackSize); 255 | int upd_i = resultIndex; 256 | ++resultIndex; 257 | makeEntry(_rstor, upd_i, temp, sta, NULL, NULL); 258 | return lastendind; 259 | } 260 | 261 | const char* turnToUse(int index, const char* varName, int* pstackSize, short leftside, int contra1, int contra2) 262 | { 263 | char temp[5] = {0}; 264 | if(varName[0] == 'p') 265 | { 266 | temp[0] = 'a'; 267 | sprintf(temp+1, "%s", varName+1); 268 | return strdup(temp); 269 | } 270 | int varIndex; 271 | short imme = false; 272 | if(varName[0] == 't') varIndex = tvarIndex[atoi(varName+1)]; 273 | else if(varName[0] == 'T') varIndex = TvarIndex[atoi(varName+1)]; 274 | else imme = true; 275 | 276 | if(imme == false && regIndex[varIndex] >= 0 && regIndex[varIndex] < 20) 277 | { 278 | strcpy(temp, reg2string(regIndex[varIndex])); 279 | return strdup(temp); 280 | } 281 | 282 | int regnum = suitableReg(pstackSize, contra1, contra2); 283 | 284 | strcpy(temp, reg2string(regnum)); 285 | if(imme == true) 286 | { 287 | int upd_i = resultIndex; 288 | ++resultIndex; 289 | makeEntry(_rassi, upd_i, reg2string(regnum), varName, NULL, NULL); 290 | regUsage[regnum] = -1; 291 | return strdup(temp); 292 | } 293 | if(regIndex[varIndex] < 0 && leftside == false) 294 | { 295 | 296 | int upd_i = resultIndex; 297 | ++resultIndex; 298 | char stackint[5] = {0}; 299 | sprintf(stackint, "%d", -regIndex[varIndex]); 300 | makeEntry(_rload, upd_i, stackint, temp, NULL, NULL); 301 | } 302 | else if(VarList[varIndex]->array == true && leftside == false) 303 | { 304 | int upd_i = resultIndex; 305 | ++resultIndex; 306 | makeEntry(_rldad, upd_i, VarList[varIndex]->globalname, temp, NULL, NULL); 307 | } 308 | if(imme == false) 309 | { 310 | regUsage[regnum] = varIndex; 311 | regIndex[varIndex] = regnum; 312 | int ending = index+1; 313 | while(ending < exprIndex && actTab[ending][varIndex] == true) 314 | ++ending; 315 | endtime[regnum] = ending; 316 | } 317 | return strdup(temp); 318 | } 319 | 320 | const char* turnParamToUse(int index, const char* varName, int* pstackSize, int StackPlace) 321 | { 322 | if(varName[0] != 'p') return turnToUse(index, varName, pstackSize, false, -1, -1); 323 | int temp = suitableReg(pstackSize, -1, -1); 324 | int upd_i = resultIndex; 325 | ++resultIndex; 326 | char sta[5] = {0}; 327 | sprintf(sta, "%d", StackPlace); 328 | makeEntry(_rload, upd_i, sta, reg2string(temp), NULL, NULL); 329 | return reg2string(temp); 330 | } 331 | 332 | void disableReg(int index) 333 | { 334 | if(index == exprIndex-1) return; 335 | ++index; 336 | int i = 0; 337 | for(; i < 19; ++i) 338 | { 339 | if(regUsage[i] >= 0 && actTab[index][regUsage[i]] == false) 340 | { 341 | if(regUsage[i] >= 0) regIndex[regUsage[i]] = 20; 342 | regUsage[i] = -2; 343 | } 344 | if(regUsage[i] == -1) 345 | regUsage[i] = -2; 346 | } 347 | return; 348 | } 349 | 350 | void changeGlobal(const char* leftvar, int* pstackSize) 351 | { 352 | int varIndex; 353 | if(leftvar[0] == 'T') varIndex = TvarIndex[atoi(leftvar+1)]; 354 | else return; 355 | if(VarList[varIndex]->global == false) return; 356 | if(VarList[varIndex]->array == true) return; 357 | const char* globalname = VarList[varIndex]->globalname; 358 | int reg0 = regIndex[varIndex]; 359 | int reg1 = suitableReg(pstackSize, reg0, -1); 360 | int upd_i = resultIndex; 361 | ++resultIndex; 362 | makeEntry(_rldad, upd_i, globalname, reg2string(reg1), NULL, NULL); 363 | upd_i = resultIndex; 364 | ++resultIndex; 365 | makeEntry(_rassi, upd_i, reg2string(reg1), reg2string(reg0), "0", NULL); 366 | return; 367 | } 368 | 369 | void handleDecl(int index, int* pstackSize) 370 | { 371 | if(ExprList[index]->dst == NULL) return; 372 | if(ExprList[index]->src1 != NULL) return; 373 | int varIndex; 374 | const char* varName = ExprList[index]->op; 375 | if(varName[0] != 'T') return; 376 | varIndex = TvarIndex[atoi(varName+1)]; 377 | char sta[5] = {0}; 378 | sprintf(sta, "%d", *pstackSize); 379 | VarList[varIndex]->globalname = sta; 380 | (*pstackSize) += (atoi(ExprList[index]->dst))/4; 381 | return; 382 | } 383 | 384 | void handleOpe2(int index, int* pstackSize) 385 | { 386 | const char* src1 = turnToUse(index, ExprList[index]->src1, pstackSize, false, -1, -1); 387 | const char* src2 = turnToUse(index, ExprList[index]->src2, pstackSize, false, string2reg(src1), -1); 388 | const char* dst = turnToUse(index, ExprList[index]->dst, pstackSize, true, string2reg(src1), string2reg(src2)); 389 | int upd_i = resultIndex; 390 | ++resultIndex; 391 | makeEntry(_rope2, upd_i, ExprList[index]->op, src1, src2, dst); 392 | changeGlobal(ExprList[index]->dst, pstackSize); 393 | disableReg(index); 394 | return; 395 | } 396 | 397 | void handleOpe1(int index, int* pstackSize) 398 | { 399 | const char* src1 = turnToUse(index, ExprList[index]->src1, pstackSize, false, -1, -1); 400 | const char* dst = turnToUse(index, ExprList[index]->dst, pstackSize, true, string2reg(src1), -1); 401 | int upd_i = resultIndex; 402 | ++resultIndex; 403 | makeEntry(_rope1, upd_i, ExprList[index]->op, src1, NULL, dst); 404 | changeGlobal(ExprList[index]->dst, pstackSize); 405 | disableReg(index); 406 | return; 407 | } 408 | 409 | void handleAssi(int index, int* pstackSize) 410 | { 411 | if(EQ(ExprList[index]->src2,"0")) 412 | { 413 | const char* src1 = turnToUse(index, ExprList[index]->op, pstackSize, false, -1, -1); 414 | const char* op = turnToUse(index, ExprList[index]->src1, pstackSize, true, string2reg(src1), -1); 415 | int upd_i = resultIndex; 416 | ++resultIndex; 417 | makeEntry(_rassi, upd_i, op, src1, NULL, NULL); 418 | changeGlobal(ExprList[index]->src1, pstackSize); 419 | disableReg(index); 420 | } 421 | else if(EQ(ExprList[index]->src2,"1")) 422 | { 423 | const char* op = "+"; 424 | const char* src1 = turnToUse(index, ExprList[index]->src1, pstackSize, false, -1, -1); 425 | const char* src2 = turnToUse(index, ExprList[index]->dst, pstackSize, false, string2reg(src1), -1); 426 | const char* dst = reg2string(suitableReg(pstackSize, string2reg(src1), string2reg(src2))); 427 | int upd_i = resultIndex; 428 | ++resultIndex; 429 | makeEntry(_rope2, upd_i, op, src1, src2, dst); 430 | upd_i = resultIndex; 431 | ++resultIndex; 432 | const char* temp = turnToUse(index, ExprList[index]->op, pstackSize, false, string2reg(dst), -1); 433 | makeEntry(_rassi, upd_i, dst, temp, "0", NULL); 434 | } 435 | else 436 | { 437 | const char* op = "+"; 438 | const char* src1 = turnToUse(index, ExprList[index]->op, pstackSize, false, -1, -1); 439 | const char* src2 = turnToUse(index, ExprList[index]->dst, pstackSize, false, string2reg(src1), -1); 440 | const char* dst = reg2string(suitableReg(pstackSize, string2reg(src1), string2reg(src2))); 441 | int upd_i = resultIndex; 442 | ++resultIndex; 443 | makeEntry(_rope2, upd_i, op, src1, src2, dst); 444 | upd_i = resultIndex; 445 | ++resultIndex; 446 | const char* temp = turnToUse(index, ExprList[index]->src1, pstackSize, false, string2reg(dst), -1); 447 | makeEntry(_rassi, upd_i, temp, dst, NULL, "0"); 448 | } 449 | } 450 | 451 | void handleIfbr(int index, int* pstackSize) 452 | { 453 | 454 | const char* src1 = turnToUse(index, ExprList[index]->src1, pstackSize, false, -1, -1); 455 | const char* src2 = turnToUse(index, ExprList[index]->src2, pstackSize, false, string2reg(src1), -1); 456 | 457 | int upd_i = resultIndex; 458 | ++resultIndex; 459 | makeEntry(_rifbr, upd_i, ExprList[index]->op , src1, src2, ExprList[index]->dst); 460 | return; 461 | } 462 | 463 | void handleGoto(int index, int *pstackSize) 464 | { 465 | int upd_i = resultIndex; 466 | ++resultIndex; 467 | makeEntry(_rgoto, upd_i, ExprList[index]->op, NULL, NULL, NULL); 468 | return; 469 | } 470 | 471 | void handlePlab(int index, int *pstackSize) 472 | { 473 | int label = atoi(ExprList[index]->op); 474 | if(gotoIndex[label]op, NULL, NULL, NULL); 479 | } 480 | int i = 0; 481 | for(i = 0; i < varIndex; ++i) 482 | { 483 | if(actTab[index+1][i] == true && (regIndex[i] == 20 || regIndex[i] < 0)) 484 | { 485 | regIndex[i] = suitableReg(pstackSize, -1, -1); 486 | regUsage[regIndex[i]] = i; 487 | if(VarList[i]->array == true) 488 | { 489 | int upd_i = resultIndex; 490 | ++resultIndex; 491 | makeEntry(_rldad, upd_i, VarList[i]->globalname, reg2string(regIndex[i]), NULL, NULL); 492 | } 493 | } 494 | } 495 | if(gotoIndex[label]>index) 496 | { 497 | int upd_i = resultIndex; 498 | ++resultIndex; 499 | makeEntry(_rplab, upd_i, ExprList[index]->op, NULL, NULL, NULL); 500 | } 501 | return; 502 | } 503 | 504 | void Translate(int pre_i) 505 | { 506 | if(pre_i >= exprIndex) return; 507 | while(ExprList[pre_i]->type != _func && pre_i < exprIndex) 508 | { 509 | int upd_i = resultIndex; 510 | ++resultIndex; 511 | char temp[5] = {0}; 512 | temp[0] = 'v'; 513 | sprintf(temp+1, "%d", globalIndex); 514 | ++globalIndex; 515 | int varIndex = TvarIndex[atoi((ExprList[pre_i]->op)+1)]; 516 | VarList[varIndex]->globalname = strdup(temp); 517 | if(ExprList[pre_i]->src2 == NULL) 518 | makeEntry(_rdecl, upd_i, (const char*)temp, NULL, NULL, NULL); 519 | else 520 | makeEntry(_rdecl, upd_i, (const char*)temp, ExprList[pre_i]->dst, NULL, NULL); 521 | ++pre_i; 522 | } 523 | if (pre_i >= exprIndex) return; 524 | int i = 0, j; 525 | for(i = 0; i < 19; ++i) funcSaveReg[i] = -1; 526 | int stackSize = 0; 527 | int funcPara = atoi(ExprList[pre_i]->src1); 528 | int upd_i = resultIndex; 529 | ++resultIndex; 530 | makeEntry(_rfunc, upd_i, ExprList[pre_i]->op, ExprList[pre_i]->src1, NULL, NULL); 531 | ++pre_i; 532 | int resultFunc = upd_i; 533 | int startStack; 534 | int paramNow = 0; 535 | 536 | while(ExprList[pre_i]->type != _ends) 537 | { 538 | switch(ExprList[pre_i]->type) 539 | { 540 | case _decl: handleDecl(pre_i++, &stackSize); break; 541 | case _ope2: handleOpe2(pre_i++, &stackSize); break; 542 | case _ope1: handleOpe1(pre_i++, &stackSize); break; 543 | case _assi: handleAssi(pre_i++, &stackSize); break; 544 | case _ifbr: handleIfbr(pre_i++, &stackSize); break; 545 | case _goto: handleGoto(pre_i++, &stackSize); break; 546 | case _plab: handlePlab(pre_i++, &stackSize); break; 547 | case _para: 548 | { 549 | if(paramNow == 0) 550 | { 551 | for(j = 0; j < 7; ++j) 552 | if(funcSaveReg[j] == -1 && regUsage[j] >= 0) 553 | { 554 | int upd_i = resultIndex; 555 | ++resultIndex; 556 | funcSaveReg[j] = stackSize; 557 | ++stackSize; 558 | char sta[5] = {0}; 559 | sprintf(sta, "%d", funcSaveReg[j]); 560 | makeEntry(_rstor, upd_i, reg2string(j), sta, NULL, NULL); 561 | } 562 | startStack = stackSize; 563 | for(j = 0; jop, &stackSize, startStack+paramNow); 587 | int upd_i = resultIndex; 588 | ++resultIndex; 589 | char temp[5] = {0}; 590 | temp[0] = 'a'; 591 | sprintf(temp+1, "%d", paramNow); 592 | makeEntry(_rassi, upd_i, temp, src1, NULL, NULL); 593 | ++paramNow; 594 | ++pre_i; 595 | break; 596 | } 597 | case _call: 598 | { 599 | if(paramNow == 0) 600 | { 601 | for(j = 0; j < 7; ++j) 602 | if(funcSaveReg[j] == -1 && regUsage[j] >= 0) 603 | { 604 | int upd_i = resultIndex; 605 | ++resultIndex; 606 | funcSaveReg[j] = stackSize; 607 | ++stackSize; 608 | char sta[5] = {0}; 609 | sprintf(sta, "%d", funcSaveReg[j]); 610 | makeEntry(_rstor, upd_i, reg2string(j), sta, NULL, NULL); 611 | } 612 | startStack = stackSize; 613 | int upd_i = resultIndex; 614 | ++resultIndex; 615 | char temp1[5] = {0}; 616 | temp1[0] = 'a'; 617 | sprintf(temp1+1, "%d", 0); 618 | char temp2[5] = {0}; 619 | sprintf(temp2, "%d", stackSize++); 620 | makeEntry(_rstor, upd_i, temp1, temp2, NULL, NULL); 621 | } 622 | int upd_i = resultIndex; 623 | ++resultIndex; 624 | makeEntry(_rcall, upd_i, ExprList[pre_i]->src1, NULL, NULL, NULL); 625 | if(ExprList[pre_i]->op != NULL) 626 | { 627 | const char* op = turnToUse(pre_i, ExprList[pre_i]->op, &stackSize, true, -1, -1); 628 | upd_i = resultIndex; 629 | resultIndex++; 630 | makeEntry(_rassi, upd_i, op, "a0", NULL, NULL); 631 | changeGlobal(ExprList[pre_i]->op, &stackSize); 632 | } 633 | disableReg(pre_i); 634 | for(i = 0; i < funcPara; ++i) 635 | { 636 | int upd_i = resultIndex; 637 | ++resultIndex; 638 | char temp1[5] = {0}; 639 | sprintf(temp1, "%d", startStack+i); 640 | char temp2[5] = {0}; 641 | temp2[0] = 'a'; 642 | sprintf(temp2+1, "%d", i); 643 | makeEntry(_rload, upd_i, temp1, temp2, NULL, NULL); 644 | } 645 | if(paramNow == 0) 646 | { 647 | int upd_i = resultIndex; 648 | ++resultIndex; 649 | char temp1[5] = {0}; 650 | sprintf(temp1, "%d", startStack); 651 | char temp2[5] = "a0"; 652 | makeEntry(_rload, upd_i, temp1, temp2, NULL, NULL); 653 | } 654 | else if(funcPara == 0) 655 | { 656 | int upd_i = resultIndex; 657 | ++resultIndex; 658 | char temp1[5] = {0}; 659 | sprintf(temp1, "%d", startStack); 660 | char temp2[5] = "a0"; 661 | makeEntry(_rload, upd_i, temp1, temp2, NULL, NULL); 662 | } 663 | for(i = 0; i < 7; ++i) 664 | { 665 | if(funcSaveReg[i] != -1) 666 | { 667 | char sta[5] = {0}; 668 | sprintf(sta, "%d", funcSaveReg[i]); 669 | int upd_i = resultIndex; 670 | ++resultIndex; 671 | makeEntry(_rload, upd_i, sta, reg2string(i), NULL, NULL); 672 | funcSaveReg[i] = -1; 673 | } 674 | } 675 | ++pre_i; 676 | paramNow = 0; 677 | break; 678 | } 679 | case _retu: 680 | { 681 | for(i = 7; i < 19; ++i) 682 | { 683 | if(funcSaveReg[i] != -1) 684 | { 685 | int upd_i = resultIndex; 686 | ++resultIndex; 687 | char sta[5] = {0}; 688 | sprintf(sta, "%d", funcSaveReg[i]); 689 | makeEntry(_rload, upd_i, sta, reg2string(i), NULL, NULL); 690 | } 691 | } 692 | const char* src1 = turnToUse(pre_i, ExprList[pre_i]->op, &stackSize, false, -1, -1); 693 | upd_i = resultIndex; 694 | ++resultIndex; 695 | makeEntry(_rassi, upd_i, "a0", src1, NULL, NULL); 696 | upd_i = resultIndex; 697 | ++resultIndex; 698 | makeEntry(_rretu, upd_i, NULL, NULL, NULL, NULL); 699 | ++pre_i; 700 | } 701 | } 702 | } 703 | 704 | 705 | upd_i = resultIndex; 706 | ++resultIndex; 707 | makeEntry(_rends, upd_i, ExprList[pre_i]->op, NULL, NULL, NULL); 708 | ++pre_i; 709 | char temp[5] = {0}; 710 | sprintf(temp, "%d", stackSize); 711 | ResList[resultFunc]->src2 = strdup(temp); 712 | Translate(pre_i); 713 | return; 714 | } 715 | 716 | void printResult() 717 | { 718 | int i = 0; 719 | for(; i < 19; ++i) regUsage[i] = -2; 720 | for(i = 0; i < 100; ++i) regIndex[i] = 20; 721 | 722 | 723 | Translate(0); 724 | 725 | for(i = 0; i < resultIndex; ++i) 726 | { 727 | switch(ResList[i]->type) 728 | { 729 | case _rfunc: 730 | fprintf(stdout, "f_%s [%s] [%s]\n", ResList[i]->op, ResList[i]->src1, ResList[i]->src2); 731 | break; 732 | case _rdecl: 733 | if(ResList[i]->src1 == NULL) fprintf(stdout, "%s = 0\n", ResList[i]->op); 734 | else fprintf(stdout, "%s = malloc %s\n", ResList[i]->op, ResList[i]->src1); 735 | break; 736 | case _rope2: 737 | fprintf(stdout, " %s = %s %s %s\n", ResList[i]->dst, ResList[i]->src1, ResList[i]->op, ResList[i]->src2); 738 | break; 739 | case _rope1: 740 | fprintf(stdout, " %s = %s %s\n", ResList[i]->dst, ResList[i]->op, ResList[i]->src1); 741 | break; 742 | case _rassi: 743 | if(ResList[i]->src2 == NULL && ResList[i]->dst == NULL) 744 | fprintf(stdout, " %s = %s\n", ResList[i]->op, ResList[i]->src1); 745 | else if(ResList[i]->src2 != NULL) 746 | fprintf(stdout, " %s[%s] = %s\n", ResList[i]->op, ResList[i]->src2, ResList[i]->src1); 747 | else fprintf(stdout, " %s = %s[%s]\n", ResList[i]->op, ResList[i]->src1, ResList[i]->dst); 748 | break; 749 | case _rifbr: 750 | fprintf(stdout, " if %s %s %s goto l%s\n", ResList[i]->src1, ResList[i]->op, ResList[i]->src2, ResList[i]->dst); 751 | break; 752 | case _rgoto: 753 | fprintf(stdout, " goto l%s\n", ResList[i]->op); 754 | break; 755 | case _rplab: 756 | fprintf(stdout, "l%s:\n", ResList[i]->op); 757 | break; 758 | case _rcall: 759 | fprintf(stdout, " call f_%s\n", ResList[i]->op); 760 | break; 761 | case _rstor: 762 | fprintf(stdout, " store %s %s\n", ResList[i]->op, ResList[i]->src1); 763 | break; 764 | case _rload: 765 | fprintf(stdout, " load %s %s\n", ResList[i]->op, ResList[i]->src1); 766 | break; 767 | case _rldad: 768 | fprintf(stdout, " loadaddr %s %s\n", ResList[i]->op, ResList[i]->src1); 769 | break; 770 | case _rretu: 771 | fprintf(stdout, " return\n"); 772 | break; 773 | case _rends: 774 | fprintf(stdout, "end f_%s\n", ResList[i]->op); 775 | break; 776 | } 777 | } 778 | return; 779 | } 780 | 781 | 782 | void testExprList() 783 | { 784 | int i = 0; 785 | for(; i < exprIndex; ++i) 786 | { 787 | fprintf(stdout, "%s\n", ExprList[i]->op); 788 | } 789 | } 790 | 791 | void testActtab() 792 | { 793 | int v = varIndex; 794 | int e = exprIndex; 795 | int i, j; 796 | for(i = 0; i < v; ++i) 797 | { 798 | fprintf(stdout, "%s: ", VarList[i]->name); 799 | for(j = 0; j < e; ++j) 800 | { 801 | fprintf(stdout, " %d", actTab[j][i]); 802 | } 803 | fprintf(stdout, "\n"); 804 | } 805 | } --------------------------------------------------------------------------------