From 9848934beb2a33c5308f13b857fd0b97ca85ca39 Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Thu, 9 Jun 2016 19:12:00 +0800 Subject: [PATCH 01/22] =?UTF-8?q?mbs0221=E7=9A=84=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Asm/asm.h | 103 ++++++++---- Asm/code.h | 12 +- Asm/data.asm | 130 +++++++------- Asm/inter.h | 20 +++ Asm/lexer.h | 34 +++- Asm/vm.cpp | 4 + Asm/vm.h | 16 +- Parser/Parser.vcxproj | 2 +- Parser/Parser.vcxproj.filters | 2 +- Parser/Text.txt | 37 ++-- Parser/data.asm | 60 ------- Parser/data.s | 103 ++++++++++++ Parser/inter.h | 309 +++++++++++++++++++++++++--------- Parser/lexer.h | 52 ++++-- Parser/main.cpp | 15 +- Parser/parser.h | 192 +++++++++++++++++---- 16 files changed, 768 insertions(+), 323 deletions(-) delete mode 100644 Parser/data.asm create mode 100644 Parser/data.s diff --git a/Asm/asm.h b/Asm/asm.h index b1fac93..1e7adc7 100644 --- a/Asm/asm.h +++ b/Asm/asm.h @@ -17,6 +17,7 @@ class Asm{ Lexer *lexer; Codes *cs; map lables; + map funcs; bool match(int kind){ if (s->kind == kind){ s = lexer->scan(); @@ -33,7 +34,7 @@ class Asm{ d->width = ((Integer*)s)->value; DS = 0; CS = d->width; - match(INT); + match(NUM); match(DATA); return d; } @@ -44,15 +45,16 @@ class Asm{ match(STORE); match('$'); l->reg = ((Integer*)s)->value; - match(INT); + match(NUM); switch (s->kind){ case '#':l->opt |= MR_A; match('#'); break; case '*':l->opt |= MR_B; match('*'); break; + case ID:l->opt |= MR_B; match(ID); break; default:break; } l->addr = ((Integer*)s)->value; l->width = 4; - match(INT); + match(NUM); return l; } Code* halt(){ @@ -70,23 +72,72 @@ class Asm{ match(LOAD); match('$'); l->reg = ((Integer*)s)->value; - match(INT); + match(NUM); switch (s->kind){ case '#':l->opt |= MR_A; match('#'); break; case '*':l->opt |= MR_B; match('*'); break; + case ID:l->opt |= MR_B; match(ID); break; default:break; } l->addr = ((Integer*)s)->value; - match(INT); + match(NUM); l->width = 4; return l; } + Code* proc(){ + Func *f = new Func; + match(PROC); + f->name = ((Word*)s)->word; + match(ID); + funcs[f->name] = f; + Code *c = new Code; + while (s->kind != END){ + switch (s->kind){ + case ID:c = label(); break; + case DATA:c = data(); break; + case CALL: c = call(); break; + case LOAD:c = load(); break; + case STORE:c = store(); break; + case HALT:c = halt(); break; + case JE: c = jmp(JE); break; + case JNE: c = jmp(JNE); break; + case JB: c = jmp(JB); break; + case JG: c = jmp(JG); break; + case JMP: c = jmp(JMP); break; + case '~':c = unary(); break; + case '+':c = arith(ADD); break; + case '-':c = arith(SUB); break; + case '*':c = arith(MUL); break; + case '/':c = arith(DIV); break; + case '%':c = arith(MOD); break; + case '<':c = arith(CMP); break; + case '>':c = arith(CMP); break; + case '=':c = arith(CMP); break; + case '!':c = arith(CMP); break; + default:printf("[%3d]find unsupport cmd '%d'\n", lexer->line, s->kind); break; + } + if (c){ f->codes.push_back(c); c->offset = f->width; f->width += c->width; } + } + match(END); + match(PROC); + return f; + } + Code* call(){ + Call *c = new Call; + match(CALL); + if (funcs.find(((Word*)s)->word) == funcs.end()){ + printf("[%3d]find unsupport cmd '%d'\n", lexer->line, s->kind); + match(ID); + return c; + } + c->func = funcs[((Word*)s)->word]; + match(ID); + return c; + } Code* label(){ - match(LABEL); if (lables.find(((Word*)s)->word) == lables.end()){ lables[((Word*)s)->word] = new Label((Word*)s, cs->width); - } - else{ + }else{ lables[((Word*)s)->word]->offset = cs->width; } match(ID); @@ -100,10 +151,10 @@ class Asm{ u->opt = NEG; match('$'); u->reg1 = ((Integer*)s)->value; - match(INT); + match(NUM); match('$'); u->reg2 = ((Integer*)s)->value; - match(INT); + match(NUM); u->width = 3; return u; } @@ -114,13 +165,13 @@ class Asm{ match(s->kind); match('$'); a->reg1 = ((Integer*)s)->value; - match(INT); + match(NUM); match('$'); a->reg2 = ((Integer*)s)->value; - match(INT); + match(NUM); match('$'); a->reg3 = ((Integer*)s)->value; - match(INT); + match(NUM); a->width = 4; return a; } @@ -151,32 +202,14 @@ class Asm{ Code *c = new Code; cs = new Codes; s = lexer->scan(); - while (s->kind != '#'){ + Code *c = new Code; + while (s->kind != END){ switch (s->kind){ - case ID:printf("[%3d]find id:%s\n", lexer->line, ((Word*)s)->word.c_str()); break; case DATA:c = data(); break; - case LOAD:c = load(); break; - case STORE:c = store(); break; - case HALT:c = halt(); break; - case LABEL:c = label(); break; - case JE: c = jmp(JE); break; - case JNE: c = jmp(JNE); break; - case JB: c = jmp(JB); break; - case JG: c = jmp(JG); break; - case JMP: c = jmp(JMP); break; - case '~':c = unary(); break; - case '+':c = arith(ADD); break; - case '-':c = arith(SUB); break; - case '*':c = arith(MUL); break; - case '/':c = arith(DIV); break; - case '%':c = arith(MOD); break; - case '<':c = arith(CMP); break; - case '>':c = arith(CMP); break; - case '=':c = arith(CMP); break; - case '!':c = arith(CMP); break; + case PROC:c = proc(); break; default:printf("[%3d]find unsupport cmd '%d'\n", lexer->line, s->kind); break; } - if (c){ cs->codes.push_back(c); c->offset = cs->width; cs->width += c->width; } + if (c){ cs->codes.push_back(c); cs->offset = cs->width; cs->width += c->width; } } } void write(FILE *fp){ diff --git a/Asm/code.h b/Asm/code.h index 7eff493..2490e3c 100644 --- a/Asm/code.h +++ b/Asm/code.h @@ -15,7 +15,17 @@ enum Tag{ MOV, IN, OUT, SHL, SHR, SAL, SAR, SRL, SRR,// LOOP, - ID = 256, INT, END, LABEL, DATA, CODE, STACK + ID = 256, NUM, END, LABEL, DATA, CODE, STACK, PROC, ENDP, CALL }; +enum REG{ + BP = 256, + SI, + DI, + CS, + DS, + ES, + SS, + SP +};// 通用寄存器 #endif \ No newline at end of file diff --git a/Asm/data.asm b/Asm/data.asm index 0cbd5a0..ea2749d 100644 --- a/Asm/data.asm +++ b/Asm/data.asm @@ -1,61 +1,69 @@ -data 4 data -load $2 #0 -store $2 *0 -load $3 #24 -store $3 *2 -load $4 #10 -store $4 *0 -label L0: -load $0 *0 -load $5 #0 -> $0 $5 $6 -jg L2 -jmp L1 -label L2: -load $0 *0 -load $7 #1 -- $0 $7 $8 -store $8 *0 -load $1 *2 -load $9 #1 -+ $1 $9 $10 -store $10 *2 -jmp L0 -label L1: -label L3: -load $0 *0 -load $11 #10 -< $0 $11 $12 -jb L5 -jmp L4 -label L5: -load $0 *0 -load $13 #1 -+ $0 $13 $14 -store $14 *0 -jmp L3 -label L4: -label L6: -load $1 *2 -load $15 #1 -- $1 $15 $16 -store $16 *2 -load $1 *2 -load $17 #12 -> $1 $17 $18 -jg L6 -jmp L7 -label L7: -load $1 *2 -load $0 *0 -! $1 $0 $19 -jne L9 -jmp L8 -label L9: -load $20 #64 -store $20 *0 -load $21 #32 -store $21 *2 -label L8: -halt -# \ No newline at end of file +data + $a [2] + $b [2] + $c [2] + $d [2] + $e [2] + $f [2] + $num [1] +data +func draw: + push bp + mov bp sp + sub sp 6 + sub sp 2 + load $8 x + load $11 10 + < $8 $11 $12 + jb L1 + jmp L0 +L1: + load $0 a + load $13 10 + - $0 $13 $14 + store $14 a +L0: + ret +endf +func main: + push bp + mov bp sp + sub sp 4 + sub sp 2 + load $19 10 + store $19 a +L2: + load $16 a + load $20 0 + > $16 $20 $21 + jg L4 + jmp L3 +L4: + load $17 b + load $24 28 + + $17 $24 $25 + store $25 b + load $17 b + load $26 30 + = $17 $26 $27 + je L8 + jmp L7 +L8: + jmp L5 +L7: + load $17 b + load $28 1 + - $17 $28 $29 + store $29 b +L5: + load $16 a + load $22 1 + - $16 $22 $23 + store $23 a + jmp L2 +L3: + push bp + mov bp sp + call draw + ret +endf \ No newline at end of file diff --git a/Asm/inter.h b/Asm/inter.h index 26504ad..1e13e49 100644 --- a/Asm/inter.h +++ b/Asm/inter.h @@ -36,6 +36,26 @@ struct Data :Code{ } }; +struct Func :Code{ + string name; + list codes; + virtual void code(FILE* fp){ + list::iterator iter; + for (iter = codes.begin(); iter != codes.end(); iter++){ + (*iter)->code(fp); + } + } +}; + +struct Call :Code{ + Func *func; + virtual void code(FILE* fp){ + Code::code(fp); + printf("call\t %s\n", func->name.c_str()); + fwrite(&opt, sizeof(BYTE), 1, fp); + } +}; + struct Load :Code{ BYTE reg; WORD addr; diff --git a/Asm/lexer.h b/Asm/lexer.h index 34a6c78..afa5166 100644 --- a/Asm/lexer.h +++ b/Asm/lexer.h @@ -56,7 +56,7 @@ struct Type :Word{ } }; -Type* Type::Int = new Type(INT, "int", 2); +Type* Type::Int = new Type(NUM, "int", 2); struct Integer :Token{ int value; @@ -92,16 +92,34 @@ class Lexer{ Lexer(string fp){ words["data"] = new Word(DATA, "data"); words["code"] = new Word(CODE, "code"); - words["int"] = new Word(INT, "int"); + // 数据操作 words["load"] = new Word(LOAD, "load"); words["store"] = new Word(STORE, "store"); + // 停机指令 words["halt"] = new Word(HALT, "halt"); - words["label"] = new Word(LABEL, "label"); + // 算术逻辑运算 + words["sub"] = new Word(SUB, "jg"); + words["add"] = new Word(ADD, "jg"); + // 跳转指令 words["jmp"] = new Word(JMP, "jmp"); words["jb"] = new Word(JB, "jb"); + words["jbe"] = new Word(JBE, "jbe"); words["je"] = new Word(JE, "je"); - words["jne"] = new Word(JNE, "jne"); + words["jge"] = new Word(JGE, "jge"); words["jg"] = new Word(JG, "jg"); + words["jne"] = new Word(JNE, "jne"); + // 函数调用 + words["call"] = new Word(CALL, "call"); + // 段寄存器 + words["bp"] = new Integer(NUM, REG::DS); + words["sp"] = new Integer(NUM, REG::CS); + words["bp"] = new Integer(NUM, REG::SS); + words["sp"] = new Integer(NUM, REG::ES); + // 寄存器 + words["bp"] = new Integer(NUM, REG::BP); + words["sp"] = new Integer(NUM, REG::SP); + words["si"] = new Integer(NUM, REG::SI); + words["di"] = new Integer(NUM, REG::DI); inf.open(fp, ios::in); } ~Lexer(){ @@ -148,7 +166,7 @@ class Lexer{ inf.read(&ch, sizeof(ch)); } while (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')); inf.seekg(-1, ios::cur); - return new Integer(INT, value); + return new Integer(NUM, value); }else{ printf("错误的十六进制!"); } @@ -159,11 +177,11 @@ class Lexer{ inf.read(&ch, sizeof(ch)); } while (ch >= '0'&&ch <= '7'); inf.seekg(-1, ios::cur); - return new Integer(INT, value); + return new Integer(NUM, value); }else{ //十进制整数0 inf.seekg(-1, ios::cur); - return new Integer(INT, 0); + return new Integer(NUM, 0); } }else{ //除0外十进制整数,5状态 @@ -172,7 +190,7 @@ class Lexer{ inf.read(&ch, sizeof(ch)); } while (isdigit(ch)); inf.seekg(-1, ios::cur);//回退一个字符 - return new Integer(INT, value); + return new Integer(NUM, value); } } return new Token(ch); diff --git a/Asm/vm.cpp b/Asm/vm.cpp index 20beaa9..3a758d6 100644 --- a/Asm/vm.cpp +++ b/Asm/vm.cpp @@ -181,6 +181,10 @@ void CPU::execute(){ RAM[ABUS + 1] = DBUS >> 8; } break; + case IN: + break; + case OUT: + break; case HALT: break; default: diff --git a/Asm/vm.h b/Asm/vm.h index c0e0f5a..7e5062b 100644 --- a/Asm/vm.h +++ b/Asm/vm.h @@ -62,14 +62,14 @@ class CPU{ private: WORD LENGTH = 0; BYTE REG[0x100]; - WORD SP, BP, SI, DI; // 通用寄存器 - WORD CS, DS, ES, SS; // 段寄存器 - WORD IN[0x100], OUT[0x100]; // I/O端口 - WORD IP; // 程序指针 - WORD IBUS, DBUS, ABUS; // 内部总线 - BYTE RAM[0x10000]; // 内存 - WORD CYCLE = 0; // 执行周期 - ALU ALU; // ALU + WORD SP, BP, SI, DI; // 通用寄存器 + WORD CS, DS, ES, SS; // 段寄存器 + WORD PORT[0x100]; // I/O端口 + WORD IP; // 程序指针 + WORD IBUS, DBUS, ABUS; // 内部总线 + BYTE RAM[0x10000]; // 内存 + WORD CYCLE = 0; // 执行周期 + ALU ALU; // ALU BYTE ReadB(){ return RAM[IP++]; } diff --git a/Parser/Parser.vcxproj b/Parser/Parser.vcxproj index 8040781..7b684cc 100644 --- a/Parser/Parser.vcxproj +++ b/Parser/Parser.vcxproj @@ -79,7 +79,7 @@ - + diff --git a/Parser/Parser.vcxproj.filters b/Parser/Parser.vcxproj.filters index d3f3096..1ac1de5 100644 --- a/Parser/Parser.vcxproj.filters +++ b/Parser/Parser.vcxproj.filters @@ -36,7 +36,7 @@ - + 璧勬簮鏂囦欢 diff --git a/Parser/Text.txt b/Parser/Text.txt index 84dec82..9db4490 100644 --- a/Parser/Text.txt +++ b/Parser/Text.txt @@ -1,22 +1,27 @@ -int a,b; +int a,b,c,d,e,f; +char num; -a = 0; -b = 24; -for(a = 10;a > 0;a = a - 1){ - b = b + 1; +int draw(int x, int y, int z){ + if(x < 10){ + a = a - 10; + } } -while(a < 10){ - a = a + 1; +int play(int x, int y, int z){ + int p; + p = x + y + z; } -do{ - b = b - 1; -}while(b > 12); - -if(b ! a){ - a = 64; - b = 32; -} -# \ No newline at end of file +int main(int a, int b){ + int w; + for(a = 10;a > 0;a = a - 1){ + b = b + 034; + if(b = 30){ + continue; + } + b = b - 1; + } + draw(10, 11, 12); + play(10, 11, 12); +} \ No newline at end of file diff --git a/Parser/data.asm b/Parser/data.asm deleted file mode 100644 index 304c2ad..0000000 --- a/Parser/data.asm +++ /dev/null @@ -1,60 +0,0 @@ -data 4 data -load $2 #0 -store $2 *0 -load $3 #24 -store $3 *2 -load $4 #10 -store $4 *0 -label L0: -load $0 *0 -load $5 #0 -> $0 $5 $6 -jg L2 -jmp L1 -label L2: -load $0 *0 -load $7 #1 -- $0 $7 $8 -store $8 *0 -load $1 *2 -load $9 #1 -+ $1 $9 $10 -store $10 *2 -jmp L0 -label L1: -label L3: -load $0 *0 -load $11 #10 -< $0 $11 $12 -jb L5 -jmp L4 -label L5: -load $0 *0 -load $13 #1 -+ $0 $13 $14 -store $14 *0 -jmp L3 -label L4: -label L6: -load $1 *2 -load $15 #1 -- $1 $15 $16 -store $16 *2 -load $1 *2 -load $17 #12 -> $1 $17 $18 -jg L6 -jmp L7 -label L7: -load $1 *2 -load $0 *0 -! $1 $0 $19 -jne L9 -jmp L8 -label L9: -load $20 #64 -store $20 *0 -load $21 #32 -store $21 *2 -label L8: -halt diff --git a/Parser/data.s b/Parser/data.s new file mode 100644 index 0000000..f68cbf5 --- /dev/null +++ b/Parser/data.s @@ -0,0 +1,103 @@ +data + $a [2] + $b [2] + $c [2] + $d [2] + $e [2] + $f [2] + $num [1] +data +proc draw: + push bp + mov bp sp + sub sp 6 + sub sp 2 + load $8 #sp + 2;x + load $11 10 + < $8 $11 $12 + jb L1 + jmp L0 +L1: + load $0 #ds + 2;a + load $13 10 + - $0 $13 $14 + store $14 a +L0: + ret +endp +proc play: + push bp + mov bp sp + sub sp 6 + sub sp 2 + load $16 #sp + 2;x + load $17 #sp + 4;y + + $16 $17 $20 + load $18 #sp + 6;z + + $20 $18 $21 + store $21 p + ret +endp +proc main: + push bp + mov bp sp + sub sp 4 + sub sp 2 + load $26 10 + store $26 a +L2: + load $23 #sp + 2;a + load $27 0 + > $23 $27 $28 + jg L4 + jmp L3 +L4: + load $24 #sp + 4;b + load $31 28 + + $24 $31 $32 + store $32 b + load $24 #sp + 4;b + load $33 30 + = $24 $33 $34 + je L8 + jmp L7 +L8: + jmp L5 +L7: + load $24 #sp + 4;b + load $35 1 + - $24 $35 $36 + store $36 b +L5: + load $23 #sp + 2;a + load $29 1 + - $23 $29 $30 + store $30 a + jmp L2 +L3: + push bp + mov bp sp + load $38 10 + load $39 11 + load $40 12 + push $40 + push $39 + push $38 + call draw + pop $38 + pop $39 + pop $40 + push bp + mov bp sp + load $42 10 + load $43 11 + load $44 12 + push $44 + push $43 + push $42 + call play + pop $42 + pop $43 + pop $44 + ret +endp diff --git a/Parser/inter.h b/Parser/inter.h index b6e412a..68652ef 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -4,14 +4,54 @@ #define __INTER_H_ #include +#include struct Node{ virtual void code(FILE *fp){ } }; +struct Nodes :Node{ + list nodes; + virtual void code(FILE *fp){ + list::iterator iter; + for (iter = nodes.begin(); iter != nodes.end(); iter++){ + (*iter)->code(fp); + } + } +}; + +//语句 +struct Stmt :Node{ + int line; + int begin, next; + static int label; + static int newlabel(){ + return label++; + } + virtual void code(FILE *fp){ + Node::code(fp); + printf("[%04d]", line); + } +}; + +int Stmt::label = 0; + +//语句块 +struct Stmts :Stmt{ + list Ss; + virtual void code(FILE *fp){ + Stmt::code(fp); + printf("stmts\n"); + list::iterator iter; + for (iter = Ss.begin(); iter != Ss.end(); iter++){ + (*iter)->code(fp); + } + } +}; + //表达式 -struct Expr :Node{ +struct Expr :Stmt{ char opt; int label; static int count; @@ -32,15 +72,15 @@ struct Cond :Expr{ Expr::code(fp); E1->code(fp); E2->code(fp); - fprintf(fp, "%c $%d $%d $%d\n", opt, E1->label, E2->label, label); + fprintf(fp, "\t%c $%d $%d $%d\n", opt, E1->label, E2->label, label); switch (opt){ - case '>':fprintf(fp, "jg L%d\n", True); break; - case '=':fprintf(fp, "je L%d\n", True); break; - case '<':fprintf(fp, "jb L%d\n", True); break; - case '!':fprintf(fp, "jne L%d\n", True); break; - default:fprintf(fp, "jmp L%d\n", True); break; + case '>':fprintf(fp, "\tjg L%d\n", True); break; + case '=':fprintf(fp, "\tje L%d\n", True); break; + case '<':fprintf(fp, "\tjb L%d\n", True); break; + case '!':fprintf(fp, "\tjne L%d\n", True); break; + default:fprintf(fp, "\tjmp L%d\n", True); break; } - fprintf(fp, "jmp L%d\n", False); + fprintf(fp, "\tjmp L%d\n", False); } }; @@ -50,9 +90,10 @@ struct Arith :Expr{ Arith(char opt, Expr *E1, Expr *E2) :Expr(opt), E1(E1), E2(E2){} virtual void code(FILE *fp){ Expr::code(fp); + E1->code(fp); E2->code(fp); - fprintf(fp, "%c $%d $%d $%d\n", opt, E1->label, E2->label, label); + fprintf(fp, "\t%c $%d $%d $%d\n", opt, E1->label, E2->label, label); } }; @@ -62,7 +103,7 @@ struct Unary :Expr{ virtual void code(FILE *fp){ Expr::code(fp); E1->code(fp); - fprintf(fp, "%c $%d $%d\n", opt, E1->label, label); + fprintf(fp, "\t%c $%d $%d\n", opt, E1->label, label); } }; @@ -71,10 +112,15 @@ struct Id :Expr{ Type *t; Word *s; int offset; - Id(Type *t, Word *s, int offset) :Expr('@'), t(t), s(s), offset(offset){ } + bool global; + Id(Type *t, Word *s) :Expr('@'), t(t), s(s){ } virtual void code(FILE *fp){ Expr::code(fp); - fprintf(fp, "load $%d *%d\n", label, offset); + if (global){ + fprintf(fp, "\tload $%d #ds + %d;%s\n", label, offset, s->word.c_str()); + }else{ + fprintf(fp, "\tload $%d #sp + %d;%s\n", label, offset, s->word.c_str()); + } } }; @@ -83,50 +129,24 @@ struct Number :Expr{ Number(Integer *s) :Expr('@'), s(s){ } virtual void code(FILE *fp){ Expr::code(fp); - fprintf(fp, "load $%d #%d\n", label, s->value); - } -}; - -//语句 -struct Stmt :Node{ - int line; - int begin, next; - static int label; - static int newlabel(){ - return label++; - } - virtual void code(FILE *fp){ - Node::code(fp); - printf("[%04d]", line); - } -}; - -//语句块 -struct Stmts :Stmt{ - list Ss; - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("stmts\n"); - list::iterator iter; - for (iter = Ss.begin(); iter != Ss.end(); iter++){ - (*iter)->code(fp); - } + int width = s->value > 256 ? 2 : 1; + fprintf(fp, "\tload $%d %d\n", label, s->value); } }; -int Stmt::label = 0; - struct Decl :Stmt{ list ids; virtual void code(FILE *fp){ Stmt::code(fp); - printf("decl\n"); - int width = 0; - list::iterator iter; - for (iter = ids.begin(); iter != ids.end(); iter++){ - width += (*iter)->t->width; - } - fprintf(fp, "data %d data\n", width); + //printf("\ndata\n"); + //fprintf(fp, "\tdata\n"); + //list::iterator iter; + //for (iter = ids.begin(); iter != ids.end(); iter++){ + // printf("\t$%s [%d]\n", (*iter)->s->word.c_str(), (*iter)->t->width); + // fprintf(fp, "\t\t$%s [%d]\n", (*iter)->s->word.c_str(), (*iter)->t->width); + //} + //printf("data\n"); + //fprintf(fp, "\tdata\n"); } }; @@ -137,7 +157,7 @@ struct Assign :Stmt{ Stmt::code(fp); printf("assign\n"); E2->code(fp); - fprintf(fp, "store $%d *%d\n", E2->label, E1->offset); + fprintf(fp, "\tstore $%d %s\n", E2->label, E1->s->word.c_str()); } }; @@ -152,9 +172,9 @@ struct If :Stmt{ C->False = next; S1->next = next; C->code(fp); - fprintf(fp, "label L%d:\n", C->True); + fprintf(fp, "L%d:\n", C->True); S1->code(fp); - fprintf(fp, "label L%d:\n", next); + fprintf(fp, "L%d:\n", next); } }; @@ -170,12 +190,12 @@ struct Else :Stmt{ C->False = newlabel(); S1->next = next; C->code(fp); - fprintf(fp, "label L%d:\n", C->True); + fprintf(fp, "L%d:\n", C->True); S1->code(fp); - fprintf(fp, "jmp L%d\n", next); - fprintf(fp, "label L%d:\n", C->False); + fprintf(fp, "\tjmp L%d\n", next); + fprintf(fp, "L%d:\n", C->False); S2->code(fp); - fprintf(fp, "label L%d:\n", next); + fprintf(fp, "L%d:\n", next); } }; @@ -190,12 +210,12 @@ struct While :Stmt{ C->True = newlabel(); C->False = next; S1->next = begin; - fprintf(fp, "label L%d:\n", begin); + fprintf(fp, "L%d:\n", begin); C->code(fp); - fprintf(fp, "label L%d:\n", C->True); + fprintf(fp, "L%d:\n", C->True); S1->code(fp); - fprintf(fp, "jmp L%d\n", begin); - fprintf(fp, "label L%d:\n", next); + fprintf(fp, "\tjmp L%d\n", begin); + fprintf(fp, "L%d:\n", next); } }; @@ -211,10 +231,10 @@ struct Do :Stmt{ C->True = begin; C->False = next; S1->next = begin; - fprintf(fp, "label L%d:\n", begin); + fprintf(fp, "L%d:\n", begin); S1->code(fp); C->code(fp); - fprintf(fp, "label L%d:\n", next); + fprintf(fp, "L%d:\n", next); } }; @@ -230,15 +250,18 @@ struct For :Stmt{ next = newlabel(); C->True = newlabel(); C->False = next; + S2->begin = newlabel(); + S2->next = newlabel(); S3->next = begin; S1->code(fp); - fprintf(fp, "label L%d:\n", begin); + fprintf(fp, "L%d:\n", begin); C->code(fp); - fprintf(fp, "label L%d:\n", C->True); - S2->code(fp); + fprintf(fp, "L%d:\n", C->True); S3->code(fp); - fprintf(fp, "jmp L%d\n", begin); - fprintf(fp, "label L%d:\n", next); + fprintf(fp, "L%d:\n", S2->begin); + S2->code(fp); + fprintf(fp, "\tjmp L%d\n", begin); + fprintf(fp, "L%d:\n", next); } }; @@ -248,19 +271,145 @@ struct Case :Stmt{ virtual void code(FILE *fp){ Stmt::code(fp); printf("case\n"); - //fprintf(fp, "jmp L%d\n", begin); - //map::iterator iter; - //for (iter = Ss.begin(); iter != Ss.end(); iter++){ - // fprintf(fp, "label L%d:\n", iter->second->begin); - // iter->second->code(fp); - //} - //fprintf(fp, "label L%d:\n", begin); - //E->code(fp); - //for (iter = Ss.begin(); iter != Ss.end(); iter++){ - // fprintf(fp, "label L%d:\n", iter->second->begin); - // fprintf(fp, "= $%d $%d $%d", E->label, ); - // iter->second->code(fp); - //} + fprintf(fp, "jmp L%d\n", begin); + map::iterator iter; + for (iter = Ss.begin(); iter != Ss.end(); iter++){ + fprintf(fp, "L%d:\n", iter->second->begin); + iter->second->code(fp); + } + fprintf(fp, "L%d:\n", begin); + E->code(fp); + for (iter = Ss.begin(); iter != Ss.end(); iter++){ + fprintf(fp, "L%d:\n", iter->second->begin); + fprintf(fp, "= $%d $%d #%d", E->label, iter->first); + iter->second->code(fp); + } + } +}; + +struct Break :Stmt{ + Stmt *stmt; + static stack cur; + Break(){ + stmt = Break::cur.top(); + } + virtual void code(FILE *fp){ + Stmt::code(fp); + printf("break\n", stmt->next); + fprintf(fp, "\tjmp L%d\n", stmt->next); + } +}; + +stack Break::cur = stack(); + +struct Continue :Stmt{ + Stmt *stmt; + static stack cur; + Continue(){ + stmt = Continue::cur.top(); + } + virtual void code(FILE *fp){ + Stmt::code(fp); + printf("continue\n", stmt->begin); + fprintf(fp, "\tjmp L%d\n", stmt->begin); + } +}; + +stack Continue::cur = stack(); + +struct Symbols{ + int id; + static int count; + list ids; + Symbols *prev; + Symbols(){ + id = count++; + ids.clear(); + prev = nullptr; + } +}; + +int Symbols::count = 0; + +struct Function : Word{ + Type *type; + Symbols *symbols; + Stmt* body; + Function(string name, Type *type) :Word(FUNCTION, name), type(type){ + kind = FUNCTION; + symbols = new Symbols; + } + virtual void code(FILE *fp){ + int width = 0; + list::iterator iter; + for (iter = symbols->ids.begin(); iter != symbols->ids.end(); iter++){ + width += (*iter)->t->width; + (*iter)->offset = width; + (*iter)->global = false; + } + fprintf(fp, "proc %s:\n", word.c_str()); + fprintf(fp, "\tpush bp\n"); + fprintf(fp, "\tmov bp sp\n"); + fprintf(fp, "\tsub sp %d\n", width);// 为参数和局部变量预留空间 + fprintf(fp, "\tsub sp %d\n", type->width);// 为返回值预留空间 + body->code(fp); + fprintf(fp, "\tret\n"); + fprintf(fp, "endp\n"); + } +}; + +struct Call :Expr{ + list args; + Function *func; + Call() :Expr('@'){ args.clear(); } + virtual void code(FILE *fp){ + Stmt::code(fp); + printf("call\n"); + fprintf(fp, "\tpush bp\n"); + fprintf(fp, "\tmov bp sp\n"); + // 传递参数 + list::iterator iter; + for (iter = args.begin(); iter != args.end(); iter++){ + (*iter)->code(fp); + } + // 传递参数入栈 + reverse(args.begin(), args.end()); + for (iter = args.begin(); iter != args.end(); iter++){ + fprintf(fp, "\tpush $%d\n", (*iter)->label); + } + // 跳转到函数体处开始执行 + fprintf(fp, "\tcall %s\n", func->word.c_str()); + // 返回参数出栈 + reverse(args.begin(), args.end()); + for (iter = args.begin(); iter != args.end(); iter++){ + fprintf(fp, "\tpop $%d\n", (*iter)->label); + } + } +}; + +struct Global :Node{ + list ids; + list funcs; + virtual void code(FILE *fp){ + Node::code(fp); + if (!ids.empty()){ + fprintf(fp, "data\n"); + int width = 0; + list::iterator iter; + for (iter = ids.begin(); iter != ids.end(); iter++){ + fprintf(fp, "\t\t$%s [%d]\n", (*iter)->s->word.c_str(), (*iter)->t->width); + width += (*iter)->t->width; + (*iter)->offset = width; + (*iter)->global = true; + } + fprintf(fp, "data\n"); + } + if (!funcs.empty()){ + list::iterator iter2; + for (iter2 = funcs.begin(); iter2 != funcs.end(); iter2++){ + (*iter2)->code(fp); + } + } } }; diff --git a/Parser/lexer.h b/Parser/lexer.h index a8cbccd..5f5a212 100644 --- a/Parser/lexer.h +++ b/Parser/lexer.h @@ -12,9 +12,11 @@ using namespace std; -//宏定义种别码 enum Tag{ - IF = 256, THEN, ELSE, DO, WHILE, FOR, CASE, ID, INT, END + IF = 256, THEN, ELSE, DO, WHILE, FOR, CASE, BREAK, CONTINUE, + BASIC, INT, CHAR, + END, + ID, NUM, FUNCTION }; // 词法单元 @@ -28,7 +30,23 @@ struct Token{ } virtual string code(){ ostringstream s; - s << kind; + switch (kind){ + case IF:s << "IF"; break; + case THEN:s << "THEN"; break; + case ELSE:s << "ELSE"; break; + case DO:s << "DO"; break; + case WHILE:s << "WHILE"; break; + case FOR:s << "FOR"; break; + case CASE:s << "CASE"; break; + case BREAK:s << "BREAK"; break; + case CONTINUE:s << "CONTINUE"; break; + case ID:s << "ID"; break; + case BASIC:s << "BASIC"; break; + case INT:s << "INT"; break; + case CHAR:s << "CHAR"; break; + case END:s << "END"; break; + default:s << (char)kind; break; + } return s.str(); } }; @@ -42,13 +60,13 @@ struct Word :Token{ return s.str(); } virtual string code(){ - return ""; + return word; } }; struct Type :Word{ int width; - static Type* Int; + static Type *Int, *Char, *Void; Type(int kind, string word, int width) :Word(kind, word), width(width){ } virtual string place(){ ostringstream s; @@ -56,11 +74,13 @@ struct Type :Word{ return s.str(); } virtual string code(){ - return ""; + return word; } }; -Type* Type::Int = new Type(INT, "int", 2); +Type* Type::Int = new Type(BASIC, "int", 2); +Type* Type::Char = new Type(BASIC, "char", 1); +Type* Type::Void = new Type(BASIC, "void", 0); struct Integer :Token{ int value; @@ -71,7 +91,7 @@ struct Integer :Token{ return s.str(); } virtual string code(){ - return ""; + return "INT"; } }; @@ -82,7 +102,9 @@ class Lexer{ public: int line = 1; Lexer(string fp){ - words["int"] = new Word(INT, "int"); + words["int"] = Type::Int; + words["char"] = Type::Char; + words["void"] = Type::Void; words["if"] = new Word(IF, "if"); words["then"] = new Word(THEN, "then"); words["else"] = new Word(ELSE, "else"); @@ -90,13 +112,15 @@ class Lexer{ words["while"] = new Word(WHILE, "while"); words["for"] = new Word(FOR, "for"); words["case"] = new Word(CASE, "case"); + words["break"] = new Word(BREAK, "break"); + words["continue"] = new Word(CONTINUE, "continue"); words["end"] = new Word(END, "end"); inf.open(fp, ios::in); } ~Lexer(){ inf.close(); words.clear(); - printf("~Lexer"); + printf("~Lexer\n"); } Token *scan() { @@ -138,7 +162,7 @@ class Lexer{ inf.read(&ch, sizeof(ch)); } while (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')); inf.seekg(-1, ios::cur); - return new Integer(INT, value); + return new Integer(NUM, value); } else{ printf("错误的十六进制!"); @@ -151,12 +175,12 @@ class Lexer{ inf.read(&ch, sizeof(ch)); } while (ch >= '0'&&ch <= '7'); inf.seekg(-1, ios::cur); - return new Integer(INT, value); + return new Integer(NUM, value); } else{ //十进制整数0 inf.seekg(-1, ios::cur); - return new Integer(INT, 0); + return new Integer(NUM, 0); } } else{ @@ -166,7 +190,7 @@ class Lexer{ inf.read(&ch, sizeof(ch)); } while (isdigit(ch)); inf.seekg(-1, ios::cur);//回退一个字符 - return new Integer(INT, value); + return new Integer(NUM, value); } } return new Token(ch); diff --git a/Parser/main.cpp b/Parser/main.cpp index 3532a52..fa1801f 100644 --- a/Parser/main.cpp +++ b/Parser/main.cpp @@ -4,15 +4,18 @@ void main(){ char a; FILE file; FILE *fp = &file; - // 编译生成中间代码 + Parser *p = new Parser("Text.txt"); + printf("开始语法分析\n"); + Node *st = p->parse(); + printf("语法分析结束\n"); printf("编译开始\n"); - Parser p("Text.txt"); - Stmt *st = p.parse(); printf(" line stmt\n"); - fopen_s(&fp, "data.asm", "w"); + fopen_s(&fp, "data.s", "w"); st->code(fp); - fprintf(fp, "halt\n"); fclose(fp); printf("编译结束\n"); + delete p; cin >> a; -} \ No newline at end of file +} + + diff --git a/Parser/parser.h b/Parser/parser.h index 55ef721..62e257d 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -9,8 +9,10 @@ class Parser{ private: Token *s; Lexer *lexer; - int width = 0; - map m; + // 符号表 + Symbols *symbols;// 局部符号表 + Global *globol; + // 匹配词法单元 bool match(int kind){ if (s->kind == kind){ s = lexer->scan(); @@ -20,27 +22,100 @@ class Parser{ printf("%s not matched.\n", kind); return false; } - void putId(Id *id){ - m[id->s->word] = id; - } + // 符号表管理 Id* getId(){ - string str = ((Word*)s)->word; - if (m.find(str) == m.end()){ - return nullptr; + list::iterator iter; + Symbols *table = nullptr; + for (table = symbols; table != nullptr; table = table->prev){ + for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ + if ((*iter)->s->word == ((Word*)s)->word){ + return (*iter); + } + } + } + printf("[%d] %s undeclared.\n", lexer->line, ((Word*)s)->word.c_str()); + return nullptr; + } + // 外部结构 + void node(){ + while (s->kind == BASIC){ + node_decl(); + } + } + void node_decl(){ + Type *type = (Type*)s; + match(BASIC); + Token *token = s; + match(ID); + if (s->kind == '('){ + // 函数体分析 + Function *f = node_func(((Word*)token)->word, type); + globol->funcs.push_back(f); + } + else{ + Id *id = new Id(type, (Word*)token); + symbols->ids.push_back(id); + globol->ids.push_back(id); + while (s->kind == ','){ + match(','); + id = new Id(type, (Word*)s); + symbols->ids.push_back(id); + globol->ids.push_back(id); + match(ID); + } + match(';'); + } + return; + } + Function* node_func(string name, Type *type){ + Function *f = new Function(name, type); + symbols->ids.push_back(new Id(type, f)); + // 符号表入栈 + f->symbols->prev = symbols; + symbols = f->symbols; + match('('); + int offset = 0; + if (s->kind == BASIC){ + Type *type = (Type*)s; + match(BASIC); + symbols->ids.push_back(new Id(type, (Word*)s)); + match(ID); + while (s->kind == ','){ + match(','); + match(BASIC); + symbols->ids.push_back(new Id(type, (Word*)s)); + match(ID); + } } - return m[str]; + match(')'); + f->body = stmts(); + // 符号表出栈 + symbols = symbols->prev; + return f; } + // 语法分析子程序 Stmt* stmt() { Stmt *st = nullptr; + // 语法分析 switch (s->kind){ - case INT:st = stmt_decl(); break; - case ID:st = stmt_assign(); break; + case BASIC:st = stmt_decl(); break; + case ID: + { + switch (getId()->s->kind){ + case ID:st = stmt_assign(); break; + case FUNCTION:st = expr_call(); match(';'); break; + default:printf("unknown id.\n"); break; + } + break; + } case IF:st = stmt_if(); break; case WHILE:st = stmt_while(); break; case DO:st = stmt_do(); break; case FOR:st = stmt_for(); break; case CASE:st = stmt_case(); break; + case BREAK:st = stmt_break(); break; + case CONTINUE:st = stmt_continue(); break; case ';':match(';'); break; case '{':st = stmts(); break; default:match(s->kind); break; @@ -49,6 +124,11 @@ class Parser{ } Stmt* stmts(){ Stmts *sts = new Stmts; + // 符号表入栈 + Symbols *table = new Symbols; + table->prev = symbols; + symbols = table; + // 语法分析 sts->line = lexer->line; match('{'); while (s->kind != '}'){ @@ -56,21 +136,20 @@ class Parser{ if (st)sts->Ss.push_back(st); } match('}'); + // 符号表出栈 + symbols = symbols->prev; return sts; } Stmt* stmt_decl(){ Decl *d = new Decl; d->line = lexer->line; - match(INT); - putId(new Id(Type::Int, (Word*)s, width)); - d->ids.push_back(getId()); - width += Type::Int->width; + Type *type = (Type*)s; + match(BASIC); + symbols->ids.push_back(new Id(type, (Word*)s)); match(ID); while (s->kind == ','){ match(','); - putId(new Id(Type::Int, (Word*)s, width)); - d->ids.push_back(getId()); - width += Type::Int->width; + symbols->ids.push_back(new Id(type, (Word*)s)); match(ID); } match(';'); @@ -111,17 +190,25 @@ class Parser{ match('('); w->C = expr_cond(); match(')'); + Break::cur.push(w); + Continue::cur.push(w);// continue 跳转到语句开头执行 w->S1 = stmt(); + Continue::cur.pop(); + Break::cur.pop(); return w; } Stmt* stmt_do(){ Do *d = new Do; d->line = lexer->line; match(DO); + Break::cur.push(d); + Continue::cur.push(d);// continue 跳转到语句开头执行 d->S1 = stmt(); - match(WHILE); + Continue::cur.pop(); + Break::cur.pop(); + match(WHILE); match('('); - d->C = expr_cond(); + d->C = expr_cond(); match(')'); match(';'); return d; @@ -137,7 +224,11 @@ class Parser{ match(';'); f->S2 = stmt_assign(); match(')'); + Break::cur.push(f); + Continue::cur.push(f->S2);// continue直接跳转到第二条赋值语句开头执行 f->S3 = stmt(); + Continue::cur.pop(); + Break::cur.pop(); return f; } Stmt* stmt_case(){ @@ -154,6 +245,20 @@ class Parser{ match(END); return c; } + Stmt* stmt_break(){ + Break *st = new Break(); + st->line = lexer->line; + match(BREAK); + match(';'); + return st; + } + Stmt* stmt_continue(){ + Continue *st = new Continue(); + st->line = lexer->line; + match(CONTINUE); + match(';'); + return st; + } Cond* expr_cond() { Expr* e = expr_expr(); @@ -193,7 +298,8 @@ class Parser{ if (s->kind == '~'){ match('~'); u = new Unary('~', expr_unary()); - }else{ + } + else{ u = expr_factor(); } return u; @@ -203,29 +309,51 @@ class Parser{ Expr* e = nullptr; switch (s->kind){ case '(': match('('); e = expr_expr(); match(')'); break; - case ID: e = getId(); match(ID); break; - case INT: e = new Number((Integer*)s); match(INT); break; + case ID: + { + switch (getId()->s->kind){ + case ID:e = getId(); match(ID); break; + case FUNCTION:e = expr_call(); break; + default:printf("unknown id.\n"); break; + } + break; + } + case NUM: e = new Number((Integer*)s); match(NUM); break; default: printf("F->('%c')\n", s->kind); match(s->kind); break; } return e; } + Expr* expr_call(){ + Call *c = new Call; + c->line = lexer->line; + c->func = (Function*)getId()->s; + match(ID); + // 函数调用 + match('('); + while (s->kind == ID || s->kind == NUM){ + Expr *e = expr_expr(); + if (e)c->args.push_back(e); + if (s->kind == ',') match(','); + } + match(')'); + return c; + } public: Parser(string fp){ lexer = new Lexer(fp); + symbols = new Symbols(); + globol = new Global(); } ~Parser(){ - printf("~Parser"); + printf("~Parser\n"); delete lexer; + delete symbols; + delete globol; } - Stmt* parse(){ - Stmts *sts = new Stmts; - sts->line = lexer->line; + Node* parse(){ s = lexer->scan();// 预读一个词法单元,以便启动语法分析 - while (s->kind != '#'){ - Stmt *st = stmt(); - if (st)sts->Ss.push_back(st); - } - return sts; + node(); + return globol; } }; From e96086af3c656819fee9fe028b7880a304900072 Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Thu, 9 Jun 2016 19:18:09 +0800 Subject: [PATCH 02/22] Create README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..6d419a3 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Parser-Asm-VM +涓涓紪璇戠▼搴忥紝涓涓眹缂栫▼搴忓拰涓涓畝鍗曠殑16浣嶈櫄鎷熸満锛屼竴鏉¢緳瀹炵幇浠庢簮浠g爜鍒版眹缂栫▼搴忓啀鍒拌櫄鎷熸満鏈哄櫒鎸囦护绋嬪簭鐨勮浆鎹㈣繃绋嬶紝骞跺彲浠ュ湪璇ヨ櫄鎷熸満涓婅繍琛岃铏氭嫙鏈烘満鍣ㄦ寚浠ょ▼搴 + +VM-1.2 +缁橮arser娣诲姞浜嗗嚱鏁板畾涔変笌璋冪敤璇硶 +缁橝sm娣诲姞浜嗗嚱鏁板拰鏁版嵁娈电殑瀹氫箟鍜屽嚱鏁拌皟鐢 From 2f01d3f2f4877b7c1f248c7eabb40c55e61e4852 Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Thu, 9 Jun 2016 19:18:43 +0800 Subject: [PATCH 03/22] VM-1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 缁橮arser娣诲姞浜嗗嚱鏁板畾涔変笌璋冪敤璇硶 缁橝sm娣诲姞浜嗗嚱鏁板拰鏁版嵁娈电殑瀹氫箟鍜屽嚱鏁拌皟鐢 --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 6d419a3..757e900 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,2 @@ # Parser-Asm-VM 涓涓紪璇戠▼搴忥紝涓涓眹缂栫▼搴忓拰涓涓畝鍗曠殑16浣嶈櫄鎷熸満锛屼竴鏉¢緳瀹炵幇浠庢簮浠g爜鍒版眹缂栫▼搴忓啀鍒拌櫄鎷熸満鏈哄櫒鎸囦护绋嬪簭鐨勮浆鎹㈣繃绋嬶紝骞跺彲浠ュ湪璇ヨ櫄鎷熸満涓婅繍琛岃铏氭嫙鏈烘満鍣ㄦ寚浠ょ▼搴 - -VM-1.2 -缁橮arser娣诲姞浜嗗嚱鏁板畾涔変笌璋冪敤璇硶 -缁橝sm娣诲姞浜嗗嚱鏁板拰鏁版嵁娈电殑瀹氫箟鍜屽嚱鏁拌皟鐢 From 707053016dda4f2ea80906d5118ba1f1867fb63d Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Thu, 9 Jun 2016 23:13:42 +0800 Subject: [PATCH 04/22] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86Asm=E5=92=8CPa?= =?UTF-8?q?rser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Asm/Asm.vcxproj | 2 +- Asm/Asm.vcxproj.filters | 6 +- Asm/asm.h | 147 +++++++++++++++++++++------------------- Asm/code.h | 2 +- Asm/data.asm | 69 ------------------- Asm/lexer.h | 9 +-- Asm/main.cpp | 14 ++-- Parser/Text.txt | 37 +++++----- Parser/data.s | 136 +++++++++++-------------------------- Parser/inter.h | 80 +++++++++++++++------- Parser/parser.h | 10 ++- 11 files changed, 212 insertions(+), 300 deletions(-) delete mode 100644 Asm/data.asm diff --git a/Asm/Asm.vcxproj b/Asm/Asm.vcxproj index 2083441..2a63871 100644 --- a/Asm/Asm.vcxproj +++ b/Asm/Asm.vcxproj @@ -80,7 +80,7 @@ - + diff --git a/Asm/Asm.vcxproj.filters b/Asm/Asm.vcxproj.filters index bce0d64..cc6a5e0 100644 --- a/Asm/Asm.vcxproj.filters +++ b/Asm/Asm.vcxproj.filters @@ -40,12 +40,12 @@ - - 璧勬簮鏂囦欢 - 璧勬簮鏂囦欢 + + 璧勬簮鏂囦欢 + \ No newline at end of file diff --git a/Asm/asm.h b/Asm/asm.h index 1e7adc7..7eb5a5e 100644 --- a/Asm/asm.h +++ b/Asm/asm.h @@ -26,75 +26,45 @@ class Asm{ s = lexer->scan(); return false; } - Code* data(){ - Data *d = new Data; - d->opt = NULL; - d->line = lexer->line; + void data(){ + match('.'); match(DATA); - d->width = ((Integer*)s)->value; DS = 0; - CS = d->width; - match(NUM); - match(DATA); - return d; - } - Code* store(){ - Store *l = new Store; - l->line = lexer->line; - l->opt = STORE; - match(STORE); - match('$'); - l->reg = ((Integer*)s)->value; - match(NUM); - switch (s->kind){ - case '#':l->opt |= MR_A; match('#'); break; - case '*':l->opt |= MR_B; match('*'); break; - case ID:l->opt |= MR_B; match(ID); break; - default:break; - } - l->addr = ((Integer*)s)->value; - l->width = 4; - match(NUM); - return l; + cs->offset += ((Integer*)s)->value; } - Code* halt(){ - Halt *h = new Halt; - h->line = lexer->line; - h->opt = HALT; - h->width = 1; - match(HALT); - return h; + void stack(){ + match('.'); + match(STACK); + cs->offset += ((Integer*)s)->value; } - Code* load(){ - Load *l = new Load; - l->line = lexer->line; - l->opt = LOAD; - match(LOAD); - match('$'); - l->reg = ((Integer*)s)->value; - match(NUM); - switch (s->kind){ - case '#':l->opt |= MR_A; match('#'); break; - case '*':l->opt |= MR_B; match('*'); break; - case ID:l->opt |= MR_B; match(ID); break; - default:break; + void code(){ + SS = cs->offset; + CS = cs->offset; + match('.'); + match(CODE); + cs = new Codes; + s = lexer->scan(); + Code *c = new Code; + while (s->kind == PROC){ + c = proc(); + if (c){ + cs->codes.push_back(c); + cs->offset = cs->width; + cs->width += c->width; + } } - l->addr = ((Integer*)s)->value; - match(NUM); - l->width = 4; - return l; } Code* proc(){ Func *f = new Func; match(PROC); f->name = ((Word*)s)->word; match(ID); + match(':'); funcs[f->name] = f; Code *c = new Code; - while (s->kind != END){ + while (s->kind != ENDP){ switch (s->kind){ case ID:c = label(); break; - case DATA:c = data(); break; case CALL: c = call(); break; case LOAD:c = load(); break; case STORE:c = store(); break; @@ -118,8 +88,7 @@ class Asm{ } if (c){ f->codes.push_back(c); c->offset = f->width; f->width += c->width; } } - match(END); - match(PROC); + match(ENDP); return f; } Code* call(){ @@ -134,6 +103,47 @@ class Asm{ match(ID); return c; } + Code* store(){ + Store *l = new Store; + l->line = lexer->line; + l->opt = STORE; + match(STORE); + match('$'); + l->reg = ((Integer*)s)->value; + match(NUM); + switch (s->kind){ + case '#':l->opt |= MR_A; match('#'); break;// 立即数寻址 + case '@':l->opt |= MR_B; match('*'); break;// BP间接寻址 + case '&':l->opt |= MR_B; match('*'); break;// DS间接寻址 + case ID:l->opt |= MR_B; match(ID); break; + default:break; + } + l->addr = ((Integer*)s)->value; + l->width = 4; + match(NUM); + return l; + } + Code* load(){ + Load *l = new Load; + l->line = lexer->line; + l->opt = LOAD; + match(LOAD); + match('$'); + l->reg = ((Integer*)s)->value; + match(NUM); + switch (s->kind){ + case '#':l->opt |= MR_A; match('#'); break; + case '*':l->opt |= MR_B; match('*'); break; + case '$':l->opt |= MR_B; match('$'); break; + case NUM:l->opt |= MR_A; match(NUM); break; + case ID:l->opt |= MR_B; match(ID); break; + default:break; + } + l->addr = ((Integer*)s)->value; + match(NUM); + l->width = 4; + return l; + } Code* label(){ if (lables.find(((Word*)s)->word) == lables.end()){ lables[((Word*)s)->word] = new Label((Word*)s, cs->width); @@ -192,29 +202,30 @@ class Asm{ j->width = 3; return j; } + Code* halt(){ + Halt *h = new Halt; + h->line = lexer->line; + h->opt = HALT; + h->width = 1; + match(HALT); + return h; + } public: int DS = 0; int CS = 0; + int SS = 0; Asm(string fp){ lexer = new Lexer(fp); } void parse(){ - Code *c = new Code; - cs = new Codes; - s = lexer->scan(); - Code *c = new Code; - while (s->kind != END){ - switch (s->kind){ - case DATA:c = data(); break; - case PROC:c = proc(); break; - default:printf("[%3d]find unsupport cmd '%d'\n", lexer->line, s->kind); break; - } - if (c){ cs->codes.push_back(c); cs->offset = cs->width; cs->width += c->width; } - } + data(); + stack(); + code(); } void write(FILE *fp){ fwrite(&DS, sizeof(WORD), 1, fp); fwrite(&CS, sizeof(WORD), 1, fp); + fwrite(&SS, sizeof(WORD), 1, fp); fwrite(&cs->width, sizeof(WORD), 1, fp); cs->code(fp); } diff --git a/Asm/code.h b/Asm/code.h index 2490e3c..e8c4868 100644 --- a/Asm/code.h +++ b/Asm/code.h @@ -15,7 +15,7 @@ enum Tag{ MOV, IN, OUT, SHL, SHR, SAL, SAR, SRL, SRR,// LOOP, - ID = 256, NUM, END, LABEL, DATA, CODE, STACK, PROC, ENDP, CALL + ID = 256, NUM, END, LABEL, DATA, STACK, CODE, PROC, ENDP, CALL }; enum REG{ diff --git a/Asm/data.asm b/Asm/data.asm deleted file mode 100644 index ea2749d..0000000 --- a/Asm/data.asm +++ /dev/null @@ -1,69 +0,0 @@ -data - $a [2] - $b [2] - $c [2] - $d [2] - $e [2] - $f [2] - $num [1] -data -func draw: - push bp - mov bp sp - sub sp 6 - sub sp 2 - load $8 x - load $11 10 - < $8 $11 $12 - jb L1 - jmp L0 -L1: - load $0 a - load $13 10 - - $0 $13 $14 - store $14 a -L0: - ret -endf -func main: - push bp - mov bp sp - sub sp 4 - sub sp 2 - load $19 10 - store $19 a -L2: - load $16 a - load $20 0 - > $16 $20 $21 - jg L4 - jmp L3 -L4: - load $17 b - load $24 28 - + $17 $24 $25 - store $25 b - load $17 b - load $26 30 - = $17 $26 $27 - je L8 - jmp L7 -L8: - jmp L5 -L7: - load $17 b - load $28 1 - - $17 $28 $29 - store $29 b -L5: - load $16 a - load $22 1 - - $16 $22 $23 - store $23 a - jmp L2 -L3: - push bp - mov bp sp - call draw - ret -endf \ No newline at end of file diff --git a/Asm/lexer.h b/Asm/lexer.h index afa5166..0c13dae 100644 --- a/Asm/lexer.h +++ b/Asm/lexer.h @@ -91,6 +91,7 @@ class Lexer{ int line = 1; Lexer(string fp){ words["data"] = new Word(DATA, "data"); + words["stack"] = new Word(STACK, "stack"); words["code"] = new Word(CODE, "code"); // 数据操作 words["load"] = new Word(LOAD, "load"); @@ -111,10 +112,10 @@ class Lexer{ // 函数调用 words["call"] = new Word(CALL, "call"); // 段寄存器 - words["bp"] = new Integer(NUM, REG::DS); - words["sp"] = new Integer(NUM, REG::CS); - words["bp"] = new Integer(NUM, REG::SS); - words["sp"] = new Integer(NUM, REG::ES); + words["ds"] = new Integer(NUM, REG::DS); + words["cs"] = new Integer(NUM, REG::CS); + words["ss"] = new Integer(NUM, REG::SS); + words["es"] = new Integer(NUM, REG::ES); // 寄存器 words["bp"] = new Integer(NUM, REG::BP); words["sp"] = new Integer(NUM, REG::SP); diff --git a/Asm/main.cpp b/Asm/main.cpp index 7280261..67684da 100644 --- a/Asm/main.cpp +++ b/Asm/main.cpp @@ -15,13 +15,13 @@ void main(){ printf("汇编结束\n"); // 虚拟机执行 printf("虚拟机执行\n"); - CPU CPU; - CPU.init(); - fopen_s(&fp, "data.bin", "r"); - CPU.load(fp); - fclose(fp); - CPU.execute(); - CPU.store(); + //CPU CPU; + //CPU.init(); + //fopen_s(&fp, "data.bin", "r"); + //CPU.load(fp); + //fclose(fp); + //CPU.execute(); + //CPU.store(); printf("执行结束\n"); cin >> a; } \ No newline at end of file diff --git a/Parser/Text.txt b/Parser/Text.txt index 9db4490..add1617 100644 --- a/Parser/Text.txt +++ b/Parser/Text.txt @@ -1,27 +1,22 @@ int a,b,c,d,e,f; -char num; - -int draw(int x, int y, int z){ - if(x < 10){ - a = a - 10; +int draw(int x, int y){ + int a1,b1; + a1 = x; + b1 = y; + { + int c1,d1; + c1 = a1; + d1 = b1; + { + int e1,f1; + e1 = c1; + f1 = d1; + } } } -int play(int x, int y, int z){ - int p; - p = x + y + z; -} - -int main(int a, int b){ - int w; - for(a = 10;a > 0;a = a - 1){ - b = b + 034; - if(b = 30){ - continue; - } - b = b - 1; - } - draw(10, 11, 12); - play(10, 11, 12); +int main(){ + int a; + draw(10, 11); } \ No newline at end of file diff --git a/Parser/data.s b/Parser/data.s index f68cbf5..c0df597 100644 --- a/Parser/data.s +++ b/Parser/data.s @@ -1,103 +1,43 @@ -data - $a [2] - $b [2] - $c [2] - $d [2] - $e [2] - $f [2] - $num [1] -data +.data 12 +.stack 1000 +.code proc draw: - push bp - mov bp sp - sub sp 6 - sub sp 2 - load $8 #sp + 2;x - load $11 10 - < $8 $11 $12 - jb L1 - jmp L0 -L1: - load $0 #ds + 2;a - load $13 10 - - $0 $13 $14 - store $14 a -L0: - ret -endp -proc play: - push bp - mov bp sp - sub sp 6 - sub sp 2 - load $16 #sp + 2;x - load $17 #sp + 4;y - + $16 $17 $20 - load $18 #sp + 6;z - + $20 $18 $21 - store $21 p - ret + ;x @2 + ;y @4 + ;a1 @0 + ;b1 @2 + ;c1 @4 + ;d1 @6 + ;e1 @8 + ;f1 @10 + - $sp 12 + load $7 @2 + store $7 @0;a1 + load $8 @4 + store $8 @2;b1 + load $9 @0 + store $9 @4;c1 + load $10 @2 + store $10 @6;d1 + load $11 @4 + store $11 @8;e1 + load $12 @6 + store $12 @10;f1 endp proc main: - push bp - mov bp sp - sub sp 4 - sub sp 2 - load $26 10 - store $26 a -L2: - load $23 #sp + 2;a - load $27 0 - > $23 $27 $28 - jg L4 - jmp L3 -L4: - load $24 #sp + 4;b - load $31 28 - + $24 $31 $32 - store $32 b - load $24 #sp + 4;b - load $33 30 - = $24 $33 $34 - je L8 - jmp L7 -L8: - jmp L5 -L7: - load $24 #sp + 4;b - load $35 1 - - $24 $35 $36 - store $36 b -L5: - load $23 #sp + 2;a - load $29 1 - - $23 $29 $30 - store $30 a - jmp L2 -L3: - push bp - mov bp sp - load $38 10 - load $39 11 - load $40 12 - push $40 - push $39 - push $38 + ;a @0 + - $sp 2 + load $18 10 + load $19 11 + push $bp + load $bp $sp + push $19 + push $18 + - $sp 2 call draw - pop $38 - pop $39 - pop $40 - push bp - mov bp sp - load $42 10 - load $43 11 - load $44 12 - push $44 - push $43 - push $42 - call play - pop $42 - pop $43 - pop $44 - ret + + $sp 2 + pop $18 + pop $19 + load $sp $bp + pop $bp endp diff --git a/Parser/inter.h b/Parser/inter.h index 68652ef..e29d654 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -90,7 +90,6 @@ struct Arith :Expr{ Arith(char opt, Expr *E1, Expr *E2) :Expr(opt), E1(E1), E2(E2){} virtual void code(FILE *fp){ Expr::code(fp); - E1->code(fp); E2->code(fp); fprintf(fp, "\t%c $%d $%d $%d\n", opt, E1->label, E2->label, label); @@ -117,9 +116,9 @@ struct Id :Expr{ virtual void code(FILE *fp){ Expr::code(fp); if (global){ - fprintf(fp, "\tload $%d #ds + %d;%s\n", label, offset, s->word.c_str()); + fprintf(fp, "\tload $%d &%d\n", label, offset); }else{ - fprintf(fp, "\tload $%d #sp + %d;%s\n", label, offset, s->word.c_str()); + fprintf(fp, "\tload $%d @%d\n", label, offset); } } }; @@ -157,7 +156,11 @@ struct Assign :Stmt{ Stmt::code(fp); printf("assign\n"); E2->code(fp); - fprintf(fp, "\tstore $%d %s\n", E2->label, E1->s->word.c_str()); + if (E1->global){ + fprintf(fp, "\tstore $%d &%d;%s\n", E2->label, E1->offset, E1->s->word.c_str()); + }else{ + fprintf(fp, "\tstore $%d @%d;%s\n", E2->label, E1->offset, E1->s->word.c_str()); + } } }; @@ -219,7 +222,6 @@ struct While :Stmt{ } }; - struct Do :Stmt{ Cond *C; Stmt *S1; @@ -321,11 +323,12 @@ struct Symbols{ int id; static int count; list ids; - Symbols *prev; + Symbols *prev, *next; Symbols(){ id = count++; ids.clear(); prev = nullptr; + next = nullptr; } }; @@ -333,27 +336,46 @@ int Symbols::count = 0; struct Function : Word{ Type *type; + Symbols *params; Symbols *symbols; Stmt* body; Function(string name, Type *type) :Word(FUNCTION, name), type(type){ kind = FUNCTION; + params = new Symbols; symbols = new Symbols; } virtual void code(FILE *fp){ - int width = 0; + fprintf(fp, "proc %s:\n", word.c_str()); list::iterator iter; - for (iter = symbols->ids.begin(); iter != symbols->ids.end(); iter++){ - width += (*iter)->t->width; + int width = type->width; + //reverse(params->ids.begin(), params->ids.end()); + for (iter = params->ids.begin(); iter != params->ids.end(); iter++){ (*iter)->offset = width; (*iter)->global = false; + fprintf(fp, "\t;%s @%d\n", (*iter)->s->word.c_str(), width); + width += (*iter)->t->width; + } + width = 0; + Symbols *table = symbols; + for (table = symbols; table != nullptr; table = table->next){ + for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ + (*iter)->offset = width; + (*iter)->global = false; + fprintf(fp, "\t;%s @%d\n", (*iter)->s->word.c_str(), width); + width += (*iter)->t->width; + } + } + fprintf(fp, "\t- $sp %d\n", width); + width = 0; + Symbols *table = symbols; + for (table = params; table != nullptr; table = table->next){ + for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ + (*iter)->offset = width; + (*iter)->global = false; + width += (*iter)->t->width; + } } - fprintf(fp, "proc %s:\n", word.c_str()); - fprintf(fp, "\tpush bp\n"); - fprintf(fp, "\tmov bp sp\n"); - fprintf(fp, "\tsub sp %d\n", width);// 为参数和局部变量预留空间 - fprintf(fp, "\tsub sp %d\n", type->width);// 为返回值预留空间 body->code(fp); - fprintf(fp, "\tret\n"); fprintf(fp, "endp\n"); } }; @@ -365,25 +387,33 @@ struct Call :Expr{ virtual void code(FILE *fp){ Stmt::code(fp); printf("call\n"); - fprintf(fp, "\tpush bp\n"); - fprintf(fp, "\tmov bp sp\n"); - // 传递参数 + // 计算参数 list::iterator iter; for (iter = args.begin(); iter != args.end(); iter++){ (*iter)->code(fp); } - // 传递参数入栈 + // 入栈 + fprintf(fp, "\tpush $bp\n"); + fprintf(fp, "\tload $bp $sp\n"); + // 参数入栈 reverse(args.begin(), args.end()); for (iter = args.begin(); iter != args.end(); iter++){ fprintf(fp, "\tpush $%d\n", (*iter)->label); } - // 跳转到函数体处开始执行 + // 预留返回值空间 + fprintf(fp, "\t- $sp %d\n", func->type->width); + // 调用函数 fprintf(fp, "\tcall %s\n", func->word.c_str()); - // 返回参数出栈 + // 释放返回值空间 + fprintf(fp, "\t+ $sp %d\n", func->type->width); + // 参数出栈 reverse(args.begin(), args.end()); for (iter = args.begin(); iter != args.end(); iter++){ fprintf(fp, "\tpop $%d\n", (*iter)->label); } + // 出栈 + fprintf(fp, "\tload $sp $bp\n"); + fprintf(fp, "\tpop $bp\n"); } }; @@ -393,18 +423,18 @@ struct Global :Node{ virtual void code(FILE *fp){ Node::code(fp); if (!ids.empty()){ - fprintf(fp, "data\n"); int width = 0; list::iterator iter; for (iter = ids.begin(); iter != ids.end(); iter++){ - fprintf(fp, "\t\t$%s [%d]\n", (*iter)->s->word.c_str(), (*iter)->t->width); - width += (*iter)->t->width; (*iter)->offset = width; (*iter)->global = true; + width += (*iter)->t->width; } - fprintf(fp, "data\n"); + fprintf(fp, ".data %d\n", width); + fprintf(fp, ".stack 1000\n"); } if (!funcs.empty()){ + fprintf(fp, ".code\n"); list::iterator iter2; for (iter2 = funcs.begin(); iter2 != funcs.end(); iter2++){ (*iter2)->code(fp); diff --git a/Parser/parser.h b/Parser/parser.h index 62e257d..ac3fffb 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -11,7 +11,7 @@ class Parser{ Lexer *lexer; // 符号表 Symbols *symbols;// 局部符号表 - Global *globol; + Global *globol;// 全局符号表 // 匹配词法单元 bool match(int kind){ if (s->kind == kind){ @@ -71,8 +71,8 @@ class Parser{ Function *f = new Function(name, type); symbols->ids.push_back(new Id(type, f)); // 符号表入栈 - f->symbols->prev = symbols; - symbols = f->symbols; + f->params->prev = symbols; + symbols = f->params; match('('); int offset = 0; if (s->kind == BASIC){ @@ -88,9 +88,12 @@ class Parser{ } } match(')'); + f->symbols->prev = symbols; + symbols = f->symbols; f->body = stmts(); // 符号表出栈 symbols = symbols->prev; + symbols = symbols->prev; return f; } // 语法分析子程序 @@ -126,6 +129,7 @@ class Parser{ Stmts *sts = new Stmts; // 符号表入栈 Symbols *table = new Symbols; + symbols->next = table; table->prev = symbols; symbols = table; // 语法分析 From bd91a69855bd1cfd9b1b6860cbe492250c30060d Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Thu, 9 Jun 2016 23:16:34 +0800 Subject: [PATCH 05/22] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86code.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Asm/code.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Asm/code.h b/Asm/code.h index e8c4868..0d4eb9a 100644 --- a/Asm/code.h +++ b/Asm/code.h @@ -4,7 +4,6 @@ typedef unsigned char BYTE; typedef unsigned short int WORD; -//宏定义种别码 enum Tag{ HALT, ADD, SUB, MUL, DIV, MOD, CMP,// integer operator @@ -18,14 +17,6 @@ enum Tag{ ID = 256, NUM, END, LABEL, DATA, STACK, CODE, PROC, ENDP, CALL }; -enum REG{ - BP = 256, - SI, - DI, - CS, - DS, - ES, - SS, - SP -};// 通用寄存器 +enum REG{ BP = 256, SI, DI, CS, DS, ES, SS, SP }; + #endif \ No newline at end of file From 1483677d89fb9bce98d90761638d0d791dad037d Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Fri, 10 Jun 2016 01:13:14 +0800 Subject: [PATCH 06/22] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E6=B1=87=E7=BC=96=E8=AF=AD=E5=8F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Asm/asm.h | 105 +++++++++++++++++++++++++++++++++++++----------- Asm/code.h | 2 +- Asm/data.bin | Bin 197 -> 149 bytes Asm/inter.h | 22 +++++++++- Asm/lexer.h | 18 +++++++-- Asm/main.cpp | 6 ++- Asm/vm.cpp | 1 + Parser/Text.txt | 9 +++++ Parser/data.s | 68 ++++++++++++++++++++----------- Parser/inter.h | 11 +++-- 10 files changed, 182 insertions(+), 60 deletions(-) diff --git a/Asm/asm.h b/Asm/asm.h index 7eb5a5e..39bef49 100644 --- a/Asm/asm.h +++ b/Asm/asm.h @@ -13,6 +13,9 @@ using namespace std; class Asm{ private: + int DS = 0; + int CS = 0; + int SS = 0; Token *s; Lexer *lexer; Codes *cs; @@ -27,37 +30,48 @@ class Asm{ return false; } void data(){ + printf("[%03d]data.\n", lexer->line); match('.'); match(DATA); + cs->offset = cs->width; + cs->width += ((Integer*)s)->value; DS = 0; - cs->offset += ((Integer*)s)->value; + match(NUM); } void stack(){ + printf("[%03d]stack.\n", lexer->line); match('.'); match(STACK); - cs->offset += ((Integer*)s)->value; + cs->offset = cs->width; + cs->width += ((Integer*)s)->value; + SS = cs->width; + match(NUM); } void code(){ - SS = cs->offset; - CS = cs->offset; match('.'); match(CODE); - cs = new Codes; + CS = cs->offset; s = lexer->scan(); Code *c = new Code; while (s->kind == PROC){ c = proc(); if (c){ + printf("[%03d]find proc.\n", c->line); cs->codes.push_back(c); cs->offset = cs->width; cs->width += c->width; } } + match('#'); } Code* proc(){ Func *f = new Func; + printf("[%03d]proc.\n", lexer->line); match(PROC); + f->line = lexer->line; + f->offset = cs->width; f->name = ((Word*)s)->word; + f->width = 0; match(ID); match(':'); funcs[f->name] = f; @@ -68,6 +82,8 @@ class Asm{ case CALL: c = call(); break; case LOAD:c = load(); break; case STORE:c = store(); break; + case PUSH:c = push(); break; + case POP:c = pop(); break; case HALT:c = halt(); break; case JE: c = jmp(JE); break; case JNE: c = jmp(JNE); break; @@ -75,6 +91,8 @@ class Asm{ case JG: c = jmp(JG); break; case JMP: c = jmp(JMP); break; case '~':c = unary(); break; + case ADD:c = bino(ADD); break; + case SUB:c = bino(SUB); break; case '+':c = arith(ADD); break; case '-':c = arith(SUB); break; case '*':c = arith(MUL); break; @@ -84,7 +102,7 @@ class Asm{ case '>':c = arith(CMP); break; case '=':c = arith(CMP); break; case '!':c = arith(CMP); break; - default:printf("[%3d]find unsupport cmd '%d'\n", lexer->line, s->kind); break; + default:printf("[%3d]find unsupport cmd '%c\n", lexer->line, s->kind); break; } if (c){ f->codes.push_back(c); c->offset = f->width; f->width += c->width; } } @@ -93,18 +111,47 @@ class Asm{ } Code* call(){ Call *c = new Call; + c->line = lexer->line; + printf("[%03d]call.\n", lexer->line); match(CALL); if (funcs.find(((Word*)s)->word) == funcs.end()){ - printf("[%3d]find unsupport cmd '%d'\n", lexer->line, s->kind); + printf("[%3d] '%d' undeclared function.\n", lexer->line, s->kind); match(ID); return c; } c->func = funcs[((Word*)s)->word]; match(ID); + c->width = 3; return c; } + Code* pop(){ + Pop *p = new Pop; + printf("[%03d]pop.\n", lexer->line); + p->line = lexer->line; + p->opt = POP; + match(POP); + match('$'); + p->reg = ((Integer*)s)->value; + match(NUM); + p->width = 2; + return p; + } + Code* push(){ + Push *p = new Push; + printf("[%03d]push.\n", lexer->line); + p->line = lexer->line; + p->opt = PUSH; + match(PUSH); + match('$'); + p->reg = ((Integer*)s)->value; + match(NUM); + p->width = 2; + return p; + } Code* store(){ Store *l = new Store; + Token *i = new Integer(NUM, 0);; + printf("[%03d]store.\n", lexer->line); l->line = lexer->line; l->opt = STORE; match(STORE); @@ -112,19 +159,20 @@ class Asm{ l->reg = ((Integer*)s)->value; match(NUM); switch (s->kind){ - case '#':l->opt |= MR_A; match('#'); break;// 立即数寻址 - case '@':l->opt |= MR_B; match('*'); break;// BP间接寻址 - case '&':l->opt |= MR_B; match('*'); break;// DS间接寻址 - case ID:l->opt |= MR_B; match(ID); break; + case '#':l->opt |= MR_B; match('#'); i = s; match(NUM); break;// 立即数寻址 + case '@':l->opt |= MR_B; match('@'); i = s; match(NUM); break;// BP间接寻址 + case '&':l->opt |= MR_B; match('&'); i = s; match(NUM); break;// DS间接寻址 + case '$':l->opt |= MR_B; match('$'); i = s; match(NUM); break;// DS间接寻址 default:break; } - l->addr = ((Integer*)s)->value; + l->addr = ((Integer*)i)->value; l->width = 4; - match(NUM); return l; } Code* load(){ Load *l = new Load; + Token *i = new Integer(NUM, 0); + printf("[%03d]load.\n", lexer->line); l->line = lexer->line; l->opt = LOAD; match(LOAD); @@ -132,19 +180,19 @@ class Asm{ l->reg = ((Integer*)s)->value; match(NUM); switch (s->kind){ - case '#':l->opt |= MR_A; match('#'); break; - case '*':l->opt |= MR_B; match('*'); break; - case '$':l->opt |= MR_B; match('$'); break; - case NUM:l->opt |= MR_A; match(NUM); break; - case ID:l->opt |= MR_B; match(ID); break; + case '#':l->opt |= MR_B; match('#'); i = s; match(NUM); break;// 立即数寻址 + case '@':l->opt |= MR_B; match('@'); i = s; match(NUM); break;// BP间接寻址 + case '&':l->opt |= MR_B; match('&'); i = s; match(NUM); break;// DS间接寻址 + case '$':l->opt |= MR_B; match('$'); i = s; match(NUM); break;// DS间接寻址 + case NUM:l->opt |= MR_A; i = s; match(NUM); break; default:break; } - l->addr = ((Integer*)s)->value; - match(NUM); + l->addr = ((Integer*)i)->value; l->width = 4; return l; } Code* label(){ + printf("[%03d]label.\n", lexer->line); if (lables.find(((Word*)s)->word) == lables.end()){ lables[((Word*)s)->word] = new Label((Word*)s, cs->width); }else{ @@ -156,6 +204,7 @@ class Asm{ } Code* unary(){ Unary *u = new Unary; + printf("[%03d]unary.\n", lexer->line); u->line = lexer->line; match('~'); u->opt = NEG; @@ -168,8 +217,16 @@ class Asm{ u->width = 3; return u; } + Code* bino(BYTE b){ + match(b); + match('$'); + match(NUM); + match(NUM); + return nullptr; + } Code* arith(BYTE b){ Arith *a = new Arith; + printf("[%03d]arith.\n", lexer->line); a->line = lexer->line; a->opt = b; match(s->kind); @@ -187,6 +244,7 @@ class Asm{ } Code* jmp(BYTE b){ Jmp *j = new Jmp; + printf("[%03d]jmp.\n", lexer->line); j->line = lexer->line; j->opt = b; match(s->kind); @@ -204,6 +262,7 @@ class Asm{ } Code* halt(){ Halt *h = new Halt; + printf("[%03d]halt.\n", lexer->line); h->line = lexer->line; h->opt = HALT; h->width = 1; @@ -211,22 +270,22 @@ class Asm{ return h; } public: - int DS = 0; - int CS = 0; - int SS = 0; Asm(string fp){ lexer = new Lexer(fp); } void parse(){ + cs = new Codes; data(); stack(); code(); } void write(FILE *fp){ + BYTE b = 0x00; fwrite(&DS, sizeof(WORD), 1, fp); fwrite(&CS, sizeof(WORD), 1, fp); fwrite(&SS, sizeof(WORD), 1, fp); fwrite(&cs->width, sizeof(WORD), 1, fp); + //fwrite(&b, sizeof(BYTE)*CS, 1, fp); cs->code(fp); } }; diff --git a/Asm/code.h b/Asm/code.h index 0d4eb9a..c750b78 100644 --- a/Asm/code.h +++ b/Asm/code.h @@ -17,6 +17,6 @@ enum Tag{ ID = 256, NUM, END, LABEL, DATA, STACK, CODE, PROC, ENDP, CALL }; -enum REG{ BP = 256, SI, DI, CS, DS, ES, SS, SP }; +enum REG{ BP, SI, DI, CS, DS, ES, SS, SP }; #endif \ No newline at end of file diff --git a/Asm/data.bin b/Asm/data.bin index d4cc3089560cb1d189752314954c1c90d20a3845..ac927f83281576c557c7fa29aba12e07f1a1adff 100644 GIT binary patch literal 149 zcmXYmTMhyt5Wor{`+#MH-9Na~%o$Ad$m(^RL_hk`79RJ{>-knd)<9(4Yy%Au+1VC7xYZn>Hk`=3mVGm>U3n(jLh<{ZMH!leg5tj Dy7mp2 literal 197 zcmXAj!4ZN$3`JiS*k!?8Kw-v%2P?1!D==dX_CPJxUSxb?VR>9_848r}6Pdcname.c_str()); + printf("call\t$%04x;%s\n", func->offset, func->name.c_str()); fwrite(&opt, sizeof(BYTE), 1, fp); } }; @@ -80,6 +80,26 @@ struct Store :Code{ } }; +struct Push :Code{ + BYTE reg; + virtual void code(FILE* fp){ + Code::code(fp); + printf("push\t$%02x $%02x\n", opt, reg); + fwrite(&opt, sizeof(BYTE), 1, fp); + fwrite(®, sizeof(BYTE), 1, fp); + } +};// 直接寻址 + +struct Pop :Code{ + BYTE reg; + virtual void code(FILE* fp){ + Code::code(fp); + printf("pop\t$%02x $%02x\n", opt, reg); + fwrite(&opt, sizeof(BYTE), 1, fp); + fwrite(®, sizeof(BYTE), 1, fp); + } +}; + struct Halt:Code{ virtual void code(FILE* fp){ Code::code(fp); diff --git a/Asm/lexer.h b/Asm/lexer.h index 0c13dae..f152e6b 100644 --- a/Asm/lexer.h +++ b/Asm/lexer.h @@ -99,8 +99,11 @@ class Lexer{ // 停机指令 words["halt"] = new Word(HALT, "halt"); // 算术逻辑运算 - words["sub"] = new Word(SUB, "jg"); - words["add"] = new Word(ADD, "jg"); + words["sub"] = new Word(SUB, "add"); + words["add"] = new Word(ADD, "sub"); + // 栈操作指令 + words["push"] = new Word(PUSH, "push"); + words["pop"] = new Word(POP, "pop"); // 跳转指令 words["jmp"] = new Word(JMP, "jmp"); words["jb"] = new Word(JB, "jb"); @@ -110,6 +113,8 @@ class Lexer{ words["jg"] = new Word(JG, "jg"); words["jne"] = new Word(JNE, "jne"); // 函数调用 + words["proc"] = new Word(PROC, "proc"); + words["endp"] = new Word(ENDP, "endp"); words["call"] = new Word(CALL, "call"); // 段寄存器 words["ds"] = new Integer(NUM, REG::DS); @@ -134,9 +139,16 @@ class Lexer{ char ch; do{ inf.read(&ch, sizeof(ch)); + if (ch == ';'){ + while (ch != '\n'){ + //printf("skip:%c\n", ch); + inf.read(&ch, sizeof(ch)); + } + } if (ch == '\n')line++; } while (ch == ' ' || ch == '\n' || ch == '\t'); - if (ch == EOF){ + if (inf.eof()){ + printf("end of file\n"); return new Token(END); } if (isalpha(ch)){ diff --git a/Asm/main.cpp b/Asm/main.cpp index 67684da..beb3694 100644 --- a/Asm/main.cpp +++ b/Asm/main.cpp @@ -5,9 +5,11 @@ void main(){ FILE file; FILE *fp = &file; // 汇编生成目标代码 - printf("生成目标代码\n"); - Asm Asm("data.asm"); + Asm Asm("data.s"); + printf("语法分析开始\n"); Asm.parse(); + printf("语法分析结束\n"); + printf("汇编开始\n"); printf("line width offset\n"); fopen_s(&fp, "data.bin", "w"); Asm.write(fp); diff --git a/Asm/vm.cpp b/Asm/vm.cpp index 3a758d6..f9e3648 100644 --- a/Asm/vm.cpp +++ b/Asm/vm.cpp @@ -8,6 +8,7 @@ void CPU::init(){ void CPU::load(FILE *fp){ fread(&DS, sizeof(WORD), 1, fp); fread(&CS, sizeof(WORD), 1, fp); + fread(&SS, sizeof(WORD), 1, fp); fread(&LENGTH, sizeof(WORD), 1, fp); fread(&RAM, sizeof(BYTE)* LENGTH, 1, fp); printf("DS:%04d,CS:%04d,LENGTH:%04d\n", DS, CS, LENGTH); diff --git a/Parser/Text.txt b/Parser/Text.txt index add1617..ed96c78 100644 --- a/Parser/Text.txt +++ b/Parser/Text.txt @@ -1,5 +1,11 @@ int a,b,c,d,e,f; +int play(){ + a = a - 1; + b = b - 1; + c = c - 1; +} + int draw(int x, int y){ int a1,b1; a1 = x; @@ -13,6 +19,9 @@ int draw(int x, int y){ e1 = c1; f1 = d1; } + { + play(); + } } } diff --git a/Parser/data.s b/Parser/data.s index c0df597..73cf8a1 100644 --- a/Parser/data.s +++ b/Parser/data.s @@ -1,6 +1,21 @@ .data 12 .stack 1000 .code +proc play: + sub $sp 0 + load $0 &0 + load $7 1 + - $0 $7 $8 + store $8 &0;a + load $1 &2 + load $9 1 + - $1 $9 $10 + store $10 &2;b + load $2 &4 + load $11 1 + - $2 $11 $12 + store $12 &4;c +endp proc draw: ;x @2 ;y @4 @@ -8,36 +23,41 @@ proc draw: ;b1 @2 ;c1 @4 ;d1 @6 - ;e1 @8 - ;f1 @10 - - $sp 12 - load $7 @2 - store $7 @0;a1 - load $8 @4 - store $8 @2;b1 - load $9 @0 - store $9 @4;c1 - load $10 @2 - store $10 @6;d1 - load $11 @4 - store $11 @8;e1 - load $12 @6 - store $12 @10;f1 + sub $sp 8 + load $14 @0 + store $14 @0;a1 + load $15 @2 + store $15 @2;b1 + load $16 @0 + store $16 @4;c1 + load $17 @2 + store $17 @6;d1 + load $18 @4 + store $18 @0;e1 + load $19 @6 + store $19 @0;f1 + push $bp + load $bp $sp + sub $sp 2 + call play + add $sp 2 + load $sp $bp + pop $bp endp proc main: ;a @0 - - $sp 2 - load $18 10 - load $19 11 + sub $sp 2 + load $26 10 + load $27 11 push $bp load $bp $sp - push $19 - push $18 - - $sp 2 + push $27 + push $26 + sub $sp 2 call draw - + $sp 2 - pop $18 - pop $19 + add $sp 2 + pop $26 + pop $27 load $sp $bp pop $bp endp diff --git a/Parser/inter.h b/Parser/inter.h index e29d654..9fbdc66 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -137,7 +137,7 @@ struct Decl :Stmt{ list ids; virtual void code(FILE *fp){ Stmt::code(fp); - //printf("\ndata\n"); + printf("data\n"); //fprintf(fp, "\tdata\n"); //list::iterator iter; //for (iter = ids.begin(); iter != ids.end(); iter++){ @@ -283,7 +283,7 @@ struct Case :Stmt{ E->code(fp); for (iter = Ss.begin(); iter != Ss.end(); iter++){ fprintf(fp, "L%d:\n", iter->second->begin); - fprintf(fp, "= $%d $%d #%d", E->label, iter->first); + fprintf(fp, "= $%d $%d #%d\n", E->label, iter->first); iter->second->code(fp); } } @@ -365,9 +365,8 @@ struct Function : Word{ width += (*iter)->t->width; } } - fprintf(fp, "\t- $sp %d\n", width); + fprintf(fp, "\tsub $sp %d\n", width); width = 0; - Symbols *table = symbols; for (table = params; table != nullptr; table = table->next){ for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ (*iter)->offset = width; @@ -401,11 +400,11 @@ struct Call :Expr{ fprintf(fp, "\tpush $%d\n", (*iter)->label); } // 预留返回值空间 - fprintf(fp, "\t- $sp %d\n", func->type->width); + fprintf(fp, "\tsub $sp %d\n", func->type->width); // 调用函数 fprintf(fp, "\tcall %s\n", func->word.c_str()); // 释放返回值空间 - fprintf(fp, "\t+ $sp %d\n", func->type->width); + fprintf(fp, "\tadd $sp %d\n", func->type->width); // 参数出栈 reverse(args.begin(), args.end()); for (iter = args.begin(); iter != args.end(); iter++){ From c39889f2711d40a9d16912ccae3c2e2957c18af7 Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Sun, 12 Jun 2016 00:29:10 +0800 Subject: [PATCH 07/22] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86SLR(1)?= =?UTF-8?q?=E8=AF=AD=E6=B3=95=E5=88=86=E6=9E=90=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Asm/data.s | 64 ++++++++++++++ Parser/G.txt | 1 + Parser/Parser.exe | Bin 0 -> 57344 bytes Parser/Parser.vcxproj | 2 + Parser/Parser.vcxproj.filters | 6 ++ Parser/lrparser.h | 151 ++++++++++++++++++++++++++++++++++ Parser/main.cpp | 27 +++--- 7 files changed, 240 insertions(+), 11 deletions(-) create mode 100644 Asm/data.s create mode 100644 Parser/G.txt create mode 100644 Parser/Parser.exe create mode 100644 Parser/lrparser.h diff --git a/Asm/data.s b/Asm/data.s new file mode 100644 index 0000000..12d7eee --- /dev/null +++ b/Asm/data.s @@ -0,0 +1,64 @@ +.data 12 +.stack 1000 +.code +proc play: + sub $sp 0 + load $0 &0 + load $7 1 + - $0 $7 $8 + store $8 &0;a + load $1 &2 + load $9 1 + - $1 $9 $10 + store $10 &2;b + load $2 &4 + load $11 1 + - $2 $11 $12 + store $12 &4;c +endp +proc draw: + ;x @2 + ;y @4 + ;a1 @0 + ;b1 @2 + ;c1 @4 + ;d1 @6 + sub $sp 8 + load $14 @0 + store $14 @0;a1 + load $15 @2 + store $15 @2;b1 + load $16 @0 + store $16 @4;c1 + load $17 @2 + store $17 @6;d1 + load $18 @4 + store $18 @0;e1 + load $19 @6 + store $19 @0;f1 + push $bp + load $bp $sp + sub $sp 2 + call play + add $sp 2 + load $sp $bp + pop $bp +endp +proc main: + ;a @0 + sub $sp 2 + load $26 10 + load $27 11 + push $bp + load $bp $sp + push $27 + push $26 + sub $sp 2 + call draw + add $sp 2 + pop $26 + pop $27 + load $sp $bp + pop $bp +endp +# \ No newline at end of file diff --git a/Parser/G.txt b/Parser/G.txt new file mode 100644 index 0000000..957bf97 --- /dev/null +++ b/Parser/G.txt @@ -0,0 +1 @@ +(@+@)*@+(@+@)+(@+(@+@)*@)# \ No newline at end of file diff --git a/Parser/Parser.exe b/Parser/Parser.exe new file mode 100644 index 0000000000000000000000000000000000000000..a8b3f7fb1a340ccdacd1b445b14ee956136400e9 GIT binary patch literal 57344 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 literal 0 HcmV?d00001 diff --git a/Parser/Parser.vcxproj b/Parser/Parser.vcxproj index 7b684cc..9103717 100644 --- a/Parser/Parser.vcxproj +++ b/Parser/Parser.vcxproj @@ -74,8 +74,10 @@ + + diff --git a/Parser/Parser.vcxproj.filters b/Parser/Parser.vcxproj.filters index 1ac1de5..f55bc75 100644 --- a/Parser/Parser.vcxproj.filters +++ b/Parser/Parser.vcxproj.filters @@ -34,6 +34,12 @@ 澶存枃浠 + + 澶存枃浠 + + + 璧勬簮鏂囦欢 + diff --git a/Parser/lrparser.h b/Parser/lrparser.h new file mode 100644 index 0000000..a2fa8a0 --- /dev/null +++ b/Parser/lrparser.h @@ -0,0 +1,151 @@ +#include +#include +#include +#include + +using namespace std; + +#define acc 0 +#define err 15 + +int Action[12][6] = { + { 5, err, err, 4, err, err }, // 0 + { err, 6, err, err, err, acc }, // + { err, -2, 7, err, -2, -2 }, // 2 E<-T. + { err, -4, -4, err, -4, -4 }, // 3 T<-F. + { 5, err, err, 4, err, err }, // 4 + { err, -6, -6, err, -6, -6 }, // 5 F<-id. + { 5, err, err, 4, err, err }, // + { 5, err, err, 4, err, err }, // + { err, 6, err, err, 11, err }, // + { err, -1, 7, err, -1, -1 }, // 9 E<-E+T. + { err, -3, -3, err, -3, -3 }, // 10 T<-T*F + { err, -5, -5, err, -5, -5 } // 11 F<-(E). +}; + +int GoTo[12][3] = { + { 1, 2, 3 },// 0 + { err, err, err }, // 1 + { err, err, err }, // 2 + { err, err, err }, // 3 + { 8, 2, 3 }, // 4 + { err, err, err }, // 5 + { err, 9, 3 }, // 6 + { err, err, 10 }, // 7 + { err, err, err }, // 8 + { err, err, err }, // 9 + { err, err, err }, // 10 + { err, err, err } // 11 +}; + +string str = "@+*()#"; +string nt = "ETF"; + +struct Symbol{ + char group; + string code; +}; + +int lookup(char c, int state){ + int index = str.find_first_of(c); + //printf("lookup:%d %c <- %d\n", state, c, Action[state][index]); + return Action[state][index]; +} + +int go(char c, int state){ + int index = nt.find_first_of(c); + //printf("goto:%d %c <- %d\n", state, c, GoTo[state][index]); + return GoTo[state][index]; +} + +void parse(FILE *fp){ + int state = 0, temp = 1; + char c; + stack ss; + stack sts; + ss.push(state); + fread(&c, sizeof(char), 1, fp); + while (temp){ + //cin >> a; + state = ss.top(); + temp = lookup(c, state); + if (temp > 0){ + // 移入 + ss.push(temp); + sts.push(c); + // IP指向下一个符号 + fread(&c, sizeof(char), 1, fp); + }else if (temp < 0){ + // 规约 + switch (-temp){ + case 1://E<-E+T. + printf("E<-E+T.\n"); + ss.pop(); + ss.pop(); + ss.pop(); + sts.pop(); + sts.pop(); + sts.pop(); + // reduce + sts.push('E'); + break; + case 2://E<-T. + printf("E<-T.\n"); + ss.pop(); + sts.pop(); + // reduce + sts.push('E'); + break; + case 3://T<-T*F. + printf("T<-T*F.\n"); + ss.pop(); + ss.pop(); + ss.pop(); + sts.pop(); + sts.pop(); + sts.pop(); + // reduce + sts.push('T'); + break; + case 4://T<-F. + printf("T<-F.\n"); + ss.pop(); + sts.pop(); + // reduce + sts.push('T'); + break; + case 5://F<-(E). + printf("F<-(E).\n"); + ss.pop(); + ss.pop(); + ss.pop(); + sts.pop(); + sts.pop(); + sts.pop(); + // reduce + sts.push('F'); + break; + case 6://F<-id. + printf("F<-id.\n"); + ss.pop(); + sts.pop(); + // reduce + sts.push('F'); + break; + default://ERR + printf("error action.\n"); + break; + } + // GoTo + int r = go(sts.top(), ss.top()); + if (r != err){ + ss.push(r); + }else { + temp = 0; + printf("error goto.\n"); + } + }else{ + printf("pass.\n"); + } + } +} \ No newline at end of file diff --git a/Parser/main.cpp b/Parser/main.cpp index fa1801f..30202a7 100644 --- a/Parser/main.cpp +++ b/Parser/main.cpp @@ -1,20 +1,25 @@ -#include "parser.h" +#include "lrparser.h" void main(){ char a; FILE file; FILE *fp = &file; - Parser *p = new Parser("Text.txt"); - printf("开始语法分析\n"); - Node *st = p->parse(); - printf("语法分析结束\n"); - printf("编译开始\n"); - printf(" line stmt\n"); - fopen_s(&fp, "data.s", "w"); - st->code(fp); + //Parser *p = new Parser("Text.txt"); + //printf("开始语法分析\n"); + //Node *st = p->parse(); + //printf("语法分析结束\n"); + //printf("编译开始\n"); + //printf(" line stmt\n"); + //fopen_s(&fp, "data.s", "w"); + //st->code(fp); + //fclose(fp); + //printf("编译结束\n"); + //delete p; + fopen_s(&fp, "G.txt", "r"); + printf("开始SLR(1)语法分析\n"); + parse(fp); + printf("SLR(1)语法分析结束\n"); fclose(fp); - printf("编译结束\n"); - delete p; cin >> a; } From adc77fbcf6985c66b0a64f35e307d0690f9c66b5 Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Mon, 13 Jun 2016 23:13:25 +0800 Subject: [PATCH 08/22] =?UTF-8?q?=E6=B2=A1=E5=A4=AA=E5=A4=9A=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Parser/G.txt | 2 +- Parser/lrparser.h | 40 ++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Parser/G.txt b/Parser/G.txt index 957bf97..c20320a 100644 --- a/Parser/G.txt +++ b/Parser/G.txt @@ -1 +1 @@ -(@+@)*@+(@+@)+(@+(@+@)*@)# \ No newline at end of file +@+@# \ No newline at end of file diff --git a/Parser/lrparser.h b/Parser/lrparser.h index a2fa8a0..c880405 100644 --- a/Parser/lrparser.h +++ b/Parser/lrparser.h @@ -11,16 +11,16 @@ using namespace std; int Action[12][6] = { { 5, err, err, 4, err, err }, // 0 { err, 6, err, err, err, acc }, // - { err, -2, 7, err, -2, -2 }, // 2 E<-T. - { err, -4, -4, err, -4, -4 }, // 3 T<-F. + { err, -2, 7, err, -2, -2 }, // 2 E->T. + { err, -4, -4, err, -4, -4 }, // 3 T->F. { 5, err, err, 4, err, err }, // 4 - { err, -6, -6, err, -6, -6 }, // 5 F<-id. + { err, -6, -6, err, -6, -6 }, // 5 F->id. { 5, err, err, 4, err, err }, // { 5, err, err, 4, err, err }, // { err, 6, err, err, 11, err }, // - { err, -1, 7, err, -1, -1 }, // 9 E<-E+T. - { err, -3, -3, err, -3, -3 }, // 10 T<-T*F - { err, -5, -5, err, -5, -5 } // 11 F<-(E). + { err, -1, 7, err, -1, -1 }, // 9 E->E+T. + { err, -3, -3, err, -3, -3 }, // 10 T->T*F + { err, -5, -5, err, -5, -5 } // 11 F->(E). }; int GoTo[12][3] = { @@ -48,13 +48,13 @@ struct Symbol{ int lookup(char c, int state){ int index = str.find_first_of(c); - //printf("lookup:%d %c <- %d\n", state, c, Action[state][index]); + printf("action:%d %c -> %d\n", state, c, Action[state][index]); return Action[state][index]; } int go(char c, int state){ int index = nt.find_first_of(c); - //printf("goto:%d %c <- %d\n", state, c, GoTo[state][index]); + printf("goto:%d %c -> %d\n", state, c, GoTo[state][index]); return GoTo[state][index]; } @@ -78,8 +78,8 @@ void parse(FILE *fp){ }else if (temp < 0){ // 规约 switch (-temp){ - case 1://E<-E+T. - printf("E<-E+T.\n"); + case 1://E->E+T. + printf("E->E+T.\n"); ss.pop(); ss.pop(); ss.pop(); @@ -89,15 +89,15 @@ void parse(FILE *fp){ // reduce sts.push('E'); break; - case 2://E<-T. - printf("E<-T.\n"); + case 2://E->T. + printf("E->T.\n"); ss.pop(); sts.pop(); // reduce sts.push('E'); break; - case 3://T<-T*F. - printf("T<-T*F.\n"); + case 3://T->T*F. + printf("T->T*F.\n"); ss.pop(); ss.pop(); ss.pop(); @@ -107,15 +107,15 @@ void parse(FILE *fp){ // reduce sts.push('T'); break; - case 4://T<-F. - printf("T<-F.\n"); + case 4://T->F. + printf("T->F.\n"); ss.pop(); sts.pop(); // reduce sts.push('T'); break; - case 5://F<-(E). - printf("F<-(E).\n"); + case 5://F->(E). + printf("F->(E).\n"); ss.pop(); ss.pop(); ss.pop(); @@ -125,8 +125,8 @@ void parse(FILE *fp){ // reduce sts.push('F'); break; - case 6://F<-id. - printf("F<-id.\n"); + case 6://F->id. + printf("F->id.\n"); ss.pop(); sts.pop(); // reduce From 7809e9744995fb2109e8a503a0f8fedd5259dfac Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Fri, 17 Jun 2016 01:22:33 +0800 Subject: [PATCH 09/22] =?UTF-8?q?MIPS=E6=8C=87=E4=BB=A4=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Asm/code.h | 35 +++++++++++++++++-------- Asm/inter.h | 73 ++++++++++++++++++++++++++++++++++++++++++++++++----- Asm/lexer.h | 38 +++++++++++++++++++++------- Asm/vm.h | 10 ++++++-- 4 files changed, 128 insertions(+), 28 deletions(-) diff --git a/Asm/code.h b/Asm/code.h index c750b78..45b16ce 100644 --- a/Asm/code.h +++ b/Asm/code.h @@ -3,20 +3,33 @@ typedef unsigned char BYTE; typedef unsigned short int WORD; +typedef unsigned int UINT; -enum Tag{ +// 词法单元类型 +enum Tag{ ID = 256, NUM, REG, RTYPE, ITYPE, JTYPE, END, LABEL, DATA, STACK, CODE, PROC, ENDP, CALL }; + +// 指令集 +enum Inst{ HALT, - ADD, SUB, MUL, DIV, MOD, CMP,// integer operator - JMP, JNE, JG, JE, JB, JGE, JBE, - LOAD, STORE, - PUSH, POP, - NEG, - MOV, IN, OUT, - SHL, SHR, SAL, SAR, SRL, SRR,// - LOOP, - ID = 256, NUM, END, LABEL, DATA, STACK, CODE, PROC, ENDP, CALL + ADD, SUB, MUL, DIV, MOD, CMP, // Scalar + ADDV, SUBV, MULV, DIVV, // Vector + JMP, JNE, JG, JE, JB, JGE, JBE, // Jump + LOAD, STORE, // Load/Store + PUSH, POP, // Push/Pop + NEG, // Negtive + MOV, IN, OUT, // I/O + SHL, SHR, SAL, SAR, SRL, SRR, // Shift + LOOP, // Loop +}; + +// MIPS指令集 +enum MIPS{ + ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR, SLT, SLTU, SL1, SR1, SRA, SLLV, SRLV, SRAV, JR,// R-Type + ADDI, ADDIU, ANDI, ORI, XORI, LUI, LW, SW, BEQ, BNE, SLTI, SLTIU,// I-Type + J, JAL// J-Type }; -enum REG{ BP, SI, DI, CS, DS, ES, SS, SP }; +// 寄存器 +enum Register{ AX, BX, CX, DX, BP, SI, DI, CS, DS, ES, SS, SP }; #endif \ No newline at end of file diff --git a/Asm/inter.h b/Asm/inter.h index 0ae8b42..c5396db 100644 --- a/Asm/inter.h +++ b/Asm/inter.h @@ -1,11 +1,14 @@ #include "lexer.h" +// 标签 struct Label{ Word *w; WORD offset; Label(Word *w, int offset) :w(w), offset(offset) { } }; +//----------------参考RISC指令集---------------- +// 代码 struct Code{ BYTE opt; WORD line = 0;// 当前指令在汇编文件中的位置 @@ -16,6 +19,7 @@ struct Code{ } }; +// 代码块 struct Codes :Code{ list codes; virtual void code(FILE* fp){ @@ -26,6 +30,7 @@ struct Codes :Code{ } }; +// 数据段 struct Data :Code{ virtual void code(FILE* fp){ Code::code(fp); @@ -36,6 +41,7 @@ struct Data :Code{ } }; +// 函数 struct Func :Code{ string name; list codes; @@ -47,8 +53,19 @@ struct Func :Code{ } }; +// 参数传递 +struct Param :Code{ + BYTE reg;// 寄存器 + virtual void code(FILE* fp){ + Code::code(fp); + printf("param\t$%04x;%s\n", opt, reg); + fwrite(&opt, sizeof(BYTE), 1, fp); + } +}; + +// 函数调用 struct Call :Code{ - Func *func; + Func *func;// 函数 virtual void code(FILE* fp){ Code::code(fp); printf("call\t$%04x;%s\n", func->offset, func->name.c_str()); @@ -56,9 +73,11 @@ struct Call :Code{ } }; +// Load指令 struct Load :Code{ - BYTE reg; - WORD addr; + BYTE am;// 内存地址寻址方式 + BYTE reg;// 通用寄存器 + WORD addr;// RAM地址 virtual void code(FILE* fp){ Code::code(fp); printf("load\t$%02x $%02x $%04x\n", opt, reg, addr); @@ -68,9 +87,11 @@ struct Load :Code{ } };// 直接寻址 +// Store指令 struct Store :Code{ - BYTE reg; - WORD addr; + BYTE am;// 内存地址寻址方式 + BYTE reg;// 通用寄存器 + WORD addr;// RAM地址 virtual void code(FILE* fp){ Code::code(fp); printf("store\t$%02x $%02x $%04x\n", opt, reg, addr); @@ -80,6 +101,7 @@ struct Store :Code{ } }; +// 入栈指令 struct Push :Code{ BYTE reg; virtual void code(FILE* fp){ @@ -88,8 +110,9 @@ struct Push :Code{ fwrite(&opt, sizeof(BYTE), 1, fp); fwrite(®, sizeof(BYTE), 1, fp); } -};// 直接寻址 +}; +// 出栈指令 struct Pop :Code{ BYTE reg; virtual void code(FILE* fp){ @@ -100,6 +123,7 @@ struct Pop :Code{ } }; +// 停机指令 struct Halt:Code{ virtual void code(FILE* fp){ Code::code(fp); @@ -109,6 +133,7 @@ struct Halt:Code{ } }; +// 跳转指令 struct Jmp :Code{ Label *addr; virtual void code(FILE* fp){ @@ -119,6 +144,7 @@ struct Jmp :Code{ } }; +// 双目运算指令 struct Arith :Code{ BYTE reg1, reg2, reg3; virtual void code(FILE* fp){ @@ -131,6 +157,7 @@ struct Arith :Code{ } }; +// 单目运算指令 struct Unary :Code{ BYTE reg1, reg2; virtual void code(FILE* fp){ @@ -140,4 +167,38 @@ struct Unary :Code{ fwrite(®1, sizeof(BYTE), 1, fp); fwrite(®2, sizeof(BYTE), 1, fp); } +}; + +//----------------参考MIPS指令集---------------- + +#define OP 0xFC000000 // 11111100 00000000 00000000 00000000 +#define RS 0x03E00000 // 00000011 11100000 00000000 00000000 +#define RT 0x001F0000 // 00000000 00011111 00000000 00000000 +#define RD 0x0000F800 // 00000000 00000000 11111000 00000000 +#define SHAMT 0x000007C0 // 00000000 00000000 00000111 11000000 +#define FUNC 0x0000003F // 00000000 00000000 00000000 00111111 +#define IMM 0x0000FFFF // 00000000 00000000 11111111 11111111 +#define ADDR 0x03FFFFFF // 00000011 11111111 11111111 11111111 + +struct Intruction{ + UINT inst; + WORD line = 0;// 当前指令在汇编文件中的位置 + WORD width = 0;// 当前代码所占用的宽度 + WORD offset = 0;// 当前代码段的偏移量 + virtual void code(FILE* fp){ + printf("[%04d][%04d][%04x]", line, width, offset); + fwrite(&inst, sizeof(UINT), 1, fp); + } +}; + +struct R_Type :Intruction{ + +}; + +struct I_Type :Intruction{ + +}; + +struct J_Type :Intruction{ + }; \ No newline at end of file diff --git a/Asm/lexer.h b/Asm/lexer.h index f152e6b..ec3bc96 100644 --- a/Asm/lexer.h +++ b/Asm/lexer.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,7 @@ struct Word :Token{ struct Type :Word{ int width; - static Type* Int; + static Type *Int, *Reg; Type(int kind, string word, int width) :Word(kind, word), width(width){ } virtual string place(){ ostringstream s; @@ -57,6 +58,7 @@ struct Type :Word{ }; Type* Type::Int = new Type(NUM, "int", 2); +Type* Type::Reg = new Type(REG, "int", 1); struct Integer :Token{ int value; @@ -117,15 +119,33 @@ class Lexer{ words["endp"] = new Word(ENDP, "endp"); words["call"] = new Word(CALL, "call"); // 段寄存器 - words["ds"] = new Integer(NUM, REG::DS); - words["cs"] = new Integer(NUM, REG::CS); - words["ss"] = new Integer(NUM, REG::SS); - words["es"] = new Integer(NUM, REG::ES); + words["ds"] = new Integer(REG, Register::DS); + words["cs"] = new Integer(REG, Register::CS); + words["ss"] = new Integer(REG, Register::SS); + words["es"] = new Integer(REG, Register::ES); // 寄存器 - words["bp"] = new Integer(NUM, REG::BP); - words["sp"] = new Integer(NUM, REG::SP); - words["si"] = new Integer(NUM, REG::SI); - words["di"] = new Integer(NUM, REG::DI); + words["bp"] = new Integer(REG, Register::BP); + words["sp"] = new Integer(REG, Register::SP); + words["si"] = new Integer(REG, Register::SI); + words["di"] = new Integer(REG, Register::DI); + // MIPS指令集 + // R-type + words["add"] = new Integer(RTYPE, 0x00000020); + words["addu"] = new Integer(RTYPE, 0x00000021); + words["sub"] = new Integer(RTYPE, 0x00000022); + words["subu"] = new Integer(RTYPE, 0x00000023); + words["and"] = new Integer(RTYPE, 0x00000024); + words["or"] = new Integer(RTYPE, 0x00000025); + words["xor"] = new Integer(RTYPE, 0x00000026); + words["nor"] = new Integer(RTYPE, 0x00000027); + words["slt"] = new Integer(RTYPE, 0x0000002A); + words["sltu"] = new Integer(RTYPE, 0x0000002B); + words["sll"] = new Integer(RTYPE, 0x00000000); + words["srl"] = new Integer(RTYPE, 0x00000002); + words["ara"] = new Integer(RTYPE, 0x00000003); + words["add"] = new Integer(RTYPE, 0x00000004); + words["add"] = new Integer(RTYPE, 0x00000005); + words["srav"] = new Integer(RTYPE, 0x00000006); inf.open(fp, ios::in); } ~Lexer(){ diff --git a/Asm/vm.h b/Asm/vm.h index 7e5062b..0eba496 100644 --- a/Asm/vm.h +++ b/Asm/vm.h @@ -17,8 +17,14 @@ using namespace std; #define BIT_ERR 0x0001 // 内存寻址方式 -#define MR_A 0x00// 0000立即数 -#define MR_B 0x40// 0100直接寻址 +#define MR_A 0x80// imm立即寻址 +#define MR_B 0x40// addr直接寻址 +#define MR_C 0x20// [addr]间接寻址 +#define MR_D 0x10// reg寄存器寻址 +#define MR_E 0x08// [reg]寄存器间接寻址 +#define MR_F 0x04// offset相对寻址 +#define MR_G 0x02// [BP]基址寻址 +#define MR_H 0x01// [reg+addr]变址寻址 // 字/字节操作 #define MR_BYTE 0x80 // [111][111][0][0] From 4c13623d34d1ba8d698a11247ce709a8d985681f Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Fri, 17 Jun 2016 11:29:35 +0800 Subject: [PATCH 10/22] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=AF=BB?= =?UTF-8?q?=E5=9D=80=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Asm/asm.h | 32 ++++++++++++-------------------- Asm/code.h | 10 +--------- Asm/inter.h | 34 ---------------------------------- Asm/lexer.h | 25 +++++++++++++++---------- 4 files changed, 28 insertions(+), 73 deletions(-) diff --git a/Asm/asm.h b/Asm/asm.h index 39bef49..7477230 100644 --- a/Asm/asm.h +++ b/Asm/asm.h @@ -58,7 +58,7 @@ class Asm{ if (c){ printf("[%03d]find proc.\n", c->line); cs->codes.push_back(c); - cs->offset = cs->width; + c->offset = cs->width; cs->width += c->width; } } @@ -91,8 +91,8 @@ class Asm{ case JG: c = jmp(JG); break; case JMP: c = jmp(JMP); break; case '~':c = unary(); break; - case ADD:c = bino(ADD); break; - case SUB:c = bino(SUB); break; + case ADD:c = arith(ADD); break; + case SUB:c = arith(SUB); break; case '+':c = arith(ADD); break; case '-':c = arith(SUB); break; case '*':c = arith(MUL); break; @@ -102,7 +102,7 @@ class Asm{ case '>':c = arith(CMP); break; case '=':c = arith(CMP); break; case '!':c = arith(CMP); break; - default:printf("[%3d]find unsupport cmd '%c\n", lexer->line, s->kind); break; + default:printf("[%3d]find unsupported cmd '%c\n", lexer->line, s->kind); break; } if (c){ f->codes.push_back(c); c->offset = f->width; f->width += c->width; } } @@ -159,10 +159,10 @@ class Asm{ l->reg = ((Integer*)s)->value; match(NUM); switch (s->kind){ - case '#':l->opt |= MR_B; match('#'); i = s; match(NUM); break;// 立即数寻址 - case '@':l->opt |= MR_B; match('@'); i = s; match(NUM); break;// BP间接寻址 - case '&':l->opt |= MR_B; match('&'); i = s; match(NUM); break;// DS间接寻址 - case '$':l->opt |= MR_B; match('$'); i = s; match(NUM); break;// DS间接寻址 + case NUM:l->am |= MR_A; i = s; match(NUM); break;// imm立即数寻址 + case '#':l->am |= MR_B; match('#'); i = s; match(NUM); break;// #addr直接寻址 + case '[':l->am |= MR_C; match('['); i = s; match(NUM); match(']'); break;// [addr]间接寻址 + case REG:l->am |= MR_D; i = s; match(REG); break;// reg寄存器寻址 default:break; } l->addr = ((Integer*)i)->value; @@ -180,11 +180,10 @@ class Asm{ l->reg = ((Integer*)s)->value; match(NUM); switch (s->kind){ - case '#':l->opt |= MR_B; match('#'); i = s; match(NUM); break;// 立即数寻址 - case '@':l->opt |= MR_B; match('@'); i = s; match(NUM); break;// BP间接寻址 - case '&':l->opt |= MR_B; match('&'); i = s; match(NUM); break;// DS间接寻址 - case '$':l->opt |= MR_B; match('$'); i = s; match(NUM); break;// DS间接寻址 - case NUM:l->opt |= MR_A; i = s; match(NUM); break; + case NUM:l->am |= MR_A; i = s; match(NUM); break;// imm立即数寻址 + case '#':l->am |= MR_B; match('#'); i = s; match(NUM); break;// #addr直接寻址 + case '[':l->am |= MR_C; match('['); i = s; match(NUM); match(']'); break;// [addr]间接寻址 + case REG:l->am |= MR_D; i = s; match(REG); break;// reg寄存器寻址 default:break; } l->addr = ((Integer*)i)->value; @@ -217,13 +216,6 @@ class Asm{ u->width = 3; return u; } - Code* bino(BYTE b){ - match(b); - match('$'); - match(NUM); - match(NUM); - return nullptr; - } Code* arith(BYTE b){ Arith *a = new Arith; printf("[%03d]arith.\n", lexer->line); diff --git a/Asm/code.h b/Asm/code.h index 45b16ce..074f8a1 100644 --- a/Asm/code.h +++ b/Asm/code.h @@ -12,7 +12,6 @@ enum Tag{ ID = 256, NUM, REG, RTYPE, ITYPE, JTYPE, END, LABEL, DATA, STACK, CODE enum Inst{ HALT, ADD, SUB, MUL, DIV, MOD, CMP, // Scalar - ADDV, SUBV, MULV, DIVV, // Vector JMP, JNE, JG, JE, JB, JGE, JBE, // Jump LOAD, STORE, // Load/Store PUSH, POP, // Push/Pop @@ -22,14 +21,7 @@ enum Inst{ LOOP, // Loop }; -// MIPS指令集 -enum MIPS{ - ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR, SLT, SLTU, SL1, SR1, SRA, SLLV, SRLV, SRAV, JR,// R-Type - ADDI, ADDIU, ANDI, ORI, XORI, LUI, LW, SW, BEQ, BNE, SLTI, SLTIU,// I-Type - J, JAL// J-Type -}; - // 寄存器 -enum Register{ AX, BX, CX, DX, BP, SI, DI, CS, DS, ES, SS, SP }; +enum Reg{ AX, BX, CX, DX, BP, SI, DI, CS, DS, ES, SS, SP }; #endif \ No newline at end of file diff --git a/Asm/inter.h b/Asm/inter.h index c5396db..72b9adf 100644 --- a/Asm/inter.h +++ b/Asm/inter.h @@ -168,37 +168,3 @@ struct Unary :Code{ fwrite(®2, sizeof(BYTE), 1, fp); } }; - -//----------------参考MIPS指令集---------------- - -#define OP 0xFC000000 // 11111100 00000000 00000000 00000000 -#define RS 0x03E00000 // 00000011 11100000 00000000 00000000 -#define RT 0x001F0000 // 00000000 00011111 00000000 00000000 -#define RD 0x0000F800 // 00000000 00000000 11111000 00000000 -#define SHAMT 0x000007C0 // 00000000 00000000 00000111 11000000 -#define FUNC 0x0000003F // 00000000 00000000 00000000 00111111 -#define IMM 0x0000FFFF // 00000000 00000000 11111111 11111111 -#define ADDR 0x03FFFFFF // 00000011 11111111 11111111 11111111 - -struct Intruction{ - UINT inst; - WORD line = 0;// 当前指令在汇编文件中的位置 - WORD width = 0;// 当前代码所占用的宽度 - WORD offset = 0;// 当前代码段的偏移量 - virtual void code(FILE* fp){ - printf("[%04d][%04d][%04x]", line, width, offset); - fwrite(&inst, sizeof(UINT), 1, fp); - } -}; - -struct R_Type :Intruction{ - -}; - -struct I_Type :Intruction{ - -}; - -struct J_Type :Intruction{ - -}; \ No newline at end of file diff --git a/Asm/lexer.h b/Asm/lexer.h index ec3bc96..d19d36e 100644 --- a/Asm/lexer.h +++ b/Asm/lexer.h @@ -92,6 +92,7 @@ class Lexer{ public: int line = 1; Lexer(string fp){ + inf.open(fp, ios::in); words["data"] = new Word(DATA, "data"); words["stack"] = new Word(STACK, "stack"); words["code"] = new Word(CODE, "code"); @@ -119,16 +120,18 @@ class Lexer{ words["endp"] = new Word(ENDP, "endp"); words["call"] = new Word(CALL, "call"); // 段寄存器 - words["ds"] = new Integer(REG, Register::DS); - words["cs"] = new Integer(REG, Register::CS); - words["ss"] = new Integer(REG, Register::SS); - words["es"] = new Integer(REG, Register::ES); + words["ds"] = new Integer(REG, Reg::DS); + words["cs"] = new Integer(REG, Reg::CS); + words["ss"] = new Integer(REG, Reg::SS); + words["es"] = new Integer(REG, Reg::ES); // 寄存器 - words["bp"] = new Integer(REG, Register::BP); - words["sp"] = new Integer(REG, Register::SP); - words["si"] = new Integer(REG, Register::SI); - words["di"] = new Integer(REG, Register::DI); - // MIPS指令集 + words["bp"] = new Integer(REG, Reg::BP); + words["sp"] = new Integer(REG, Reg::SP); + words["si"] = new Integer(REG, Reg::SI); + words["di"] = new Integer(REG, Reg::DI); + } + // MIPS指令集 + void MIPS(){ // R-type words["add"] = new Integer(RTYPE, 0x00000020); words["addu"] = new Integer(RTYPE, 0x00000021); @@ -146,7 +149,9 @@ class Lexer{ words["add"] = new Integer(RTYPE, 0x00000004); words["add"] = new Integer(RTYPE, 0x00000005); words["srav"] = new Integer(RTYPE, 0x00000006); - inf.open(fp, ios::in); + // I-Type + + // J-Type } ~Lexer(){ inf.close(); From 5a021381b63f3e21e16238f63fc4fa31556e965e Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Fri, 17 Jun 2016 11:35:02 +0800 Subject: [PATCH 11/22] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E8=B0=83=E7=94=A8=E7=9A=84=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Parser/G.txt | 2 +- Parser/inter.h | 1 - Parser/lrparser.h | 4 ++-- Parser/main.cpp | 32 ++++++++++++++++---------------- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/Parser/G.txt b/Parser/G.txt index c20320a..cd913b1 100644 --- a/Parser/G.txt +++ b/Parser/G.txt @@ -1 +1 @@ -@+@# \ No newline at end of file +@+(@+(@+@)*@*((@+@)*@+@)+(@+@)*@*(@+@*@))# \ No newline at end of file diff --git a/Parser/inter.h b/Parser/inter.h index 9fbdc66..814e696 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -348,7 +348,6 @@ struct Function : Word{ fprintf(fp, "proc %s:\n", word.c_str()); list::iterator iter; int width = type->width; - //reverse(params->ids.begin(), params->ids.end()); for (iter = params->ids.begin(); iter != params->ids.end(); iter++){ (*iter)->offset = width; (*iter)->global = false; diff --git a/Parser/lrparser.h b/Parser/lrparser.h index c880405..f5dbb86 100644 --- a/Parser/lrparser.h +++ b/Parser/lrparser.h @@ -48,13 +48,13 @@ struct Symbol{ int lookup(char c, int state){ int index = str.find_first_of(c); - printf("action:%d %c -> %d\n", state, c, Action[state][index]); + //printf("action:%d %c -> %d\n", state, c, Action[state][index]); return Action[state][index]; } int go(char c, int state){ int index = nt.find_first_of(c); - printf("goto:%d %c -> %d\n", state, c, GoTo[state][index]); + //printf("goto:%d %c -> %d\n", state, c, GoTo[state][index]); return GoTo[state][index]; } diff --git a/Parser/main.cpp b/Parser/main.cpp index 30202a7..17552b2 100644 --- a/Parser/main.cpp +++ b/Parser/main.cpp @@ -1,25 +1,25 @@ -#include "lrparser.h" +#include "parser.h" void main(){ char a; FILE file; FILE *fp = &file; - //Parser *p = new Parser("Text.txt"); - //printf("开始语法分析\n"); - //Node *st = p->parse(); - //printf("语法分析结束\n"); - //printf("编译开始\n"); - //printf(" line stmt\n"); - //fopen_s(&fp, "data.s", "w"); - //st->code(fp); - //fclose(fp); - //printf("编译结束\n"); - //delete p; - fopen_s(&fp, "G.txt", "r"); - printf("开始SLR(1)语法分析\n"); - parse(fp); - printf("SLR(1)语法分析结束\n"); + Parser *p = new Parser("Text.txt"); + printf("开始语法分析\n"); + Node *st = p->parse(); + printf("语法分析结束\n"); + printf("编译开始\n"); + printf(" line stmt\n"); + fopen_s(&fp, "data.s", "w"); + st->code(fp); fclose(fp); + printf("编译结束\n"); + delete p; + //fopen_s(&fp, "G.txt", "r"); + //printf("开始SLR(1)语法分析\n"); + //parse(fp); + //printf("SLR(1)语法分析结束\n"); + //fclose(fp); cin >> a; } From e8a4faecd873240ca27f90e23d1697f92ecd303c Mon Sep 17 00:00:00 2001 From: mbs0221 <1019329461@qq.com> Date: Fri, 17 Jun 2016 12:13:30 +0800 Subject: [PATCH 12/22] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E7=BF=BB?= =?UTF-8?q?=E8=AF=91=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Parser/data.s | 85 +++++++++++++++++++++++--------------------------- Parser/inter.h | 54 +++++++++++++++----------------- Parser/lexer.h | 4 +-- 3 files changed, 66 insertions(+), 77 deletions(-) diff --git a/Parser/data.s b/Parser/data.s index 73cf8a1..a2795cd 100644 --- a/Parser/data.s +++ b/Parser/data.s @@ -1,20 +1,27 @@ -.data 12 -.stack 1000 +.data + dw a + dw b + dw c + dw d + dw e + dw f +.stack + db dup(0x1000) .code proc play: sub $sp 0 - load $0 &0 - load $7 1 - - $0 $7 $8 - store $8 &0;a - load $1 &2 - load $9 1 - - $1 $9 $10 - store $10 &2;b - load $2 &4 - load $11 1 - - $2 $11 $12 - store $12 &4;c + loadw $0 a + loadb $7 1 + sub $0 $7 $8 + store a $8 + loadw $1 b + loadb $9 1 + sub $1 $9 $10 + store b $10 + loadw $2 c + loadb $11 1 + sub $2 $11 $12 + store c $12 endp proc draw: ;x @2 @@ -24,40 +31,26 @@ proc draw: ;c1 @4 ;d1 @6 sub $sp 8 - load $14 @0 - store $14 @0;a1 - load $15 @2 - store $15 @2;b1 - load $16 @0 - store $16 @4;c1 - load $17 @2 - store $17 @6;d1 - load $18 @4 - store $18 @0;e1 - load $19 @6 - store $19 @0;f1 - push $bp - load $bp $sp - sub $sp 2 - call play - add $sp 2 - load $sp $bp - pop $bp + loadw $14 x + store a1 $14 + loadw $15 y + store b1 $15 + loadw $16 a1 + store c1 $16 + loadw $17 b1 + store d1 $17 + loadw $18 c1 + store e1 $18 + loadw $19 d1 + store f1 $19 + call play 0 endp proc main: ;a @0 sub $sp 2 - load $26 10 - load $27 11 - push $bp - load $bp $sp - push $27 - push $26 - sub $sp 2 - call draw - add $sp 2 - pop $26 - pop $27 - load $sp $bp - pop $bp + loadb $26 10 + loadb $27 11 + param $27 + param $26 + call draw 2 endp diff --git a/Parser/inter.h b/Parser/inter.h index 814e696..d3c18f9 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -92,7 +92,15 @@ struct Arith :Expr{ Expr::code(fp); E1->code(fp); E2->code(fp); - fprintf(fp, "\t%c $%d $%d $%d\n", opt, E1->label, E2->label, label); + switch (opt){ + case '+':fprintf(fp, "\tadd "); break; + case '-':fprintf(fp, "\tsub "); break; + case '*':fprintf(fp, "\tmul "); break; + case '/':fprintf(fp, "\tdiv "); break; + case '&':fprintf(fp, "\tand "); break; + default:break; + } + fprintf(fp, "$%d $%d $%d\n", E1->label, E2->label, label); } }; @@ -115,10 +123,11 @@ struct Id :Expr{ Id(Type *t, Word *s) :Expr('@'), t(t), s(s){ } virtual void code(FILE *fp){ Expr::code(fp); + char width = t == Type::Int ? 'w' : 'b'; if (global){ - fprintf(fp, "\tload $%d &%d\n", label, offset); + fprintf(fp, "\tload%c $%d %s\n", width, label, s->word.c_str()); }else{ - fprintf(fp, "\tload $%d @%d\n", label, offset); + fprintf(fp, "\tload%c $%d %s\n", width, label, s->word.c_str()); } } }; @@ -128,8 +137,8 @@ struct Number :Expr{ Number(Integer *s) :Expr('@'), s(s){ } virtual void code(FILE *fp){ Expr::code(fp); - int width = s->value > 256 ? 2 : 1; - fprintf(fp, "\tload $%d %d\n", label, s->value); + char width = s->value > 256 ? 'w' : 'b'; + fprintf(fp, "\tload%c $%d %d\n", width, label, s->value); } }; @@ -157,9 +166,9 @@ struct Assign :Stmt{ printf("assign\n"); E2->code(fp); if (E1->global){ - fprintf(fp, "\tstore $%d &%d;%s\n", E2->label, E1->offset, E1->s->word.c_str()); + fprintf(fp, "\tstore %s $%d\n", E1->s->word.c_str(), E2->label); }else{ - fprintf(fp, "\tstore $%d @%d;%s\n", E2->label, E1->offset, E1->s->word.c_str()); + fprintf(fp, "\tstore %s $%d\n", E1->s->word.c_str(), E2->label); } } }; @@ -385,33 +394,18 @@ struct Call :Expr{ virtual void code(FILE *fp){ Stmt::code(fp); printf("call\n"); - // 计算参数 + // 参数计算 list::iterator iter; for (iter = args.begin(); iter != args.end(); iter++){ (*iter)->code(fp); } - // 入栈 - fprintf(fp, "\tpush $bp\n"); - fprintf(fp, "\tload $bp $sp\n"); - // 参数入栈 - reverse(args.begin(), args.end()); - for (iter = args.begin(); iter != args.end(); iter++){ - fprintf(fp, "\tpush $%d\n", (*iter)->label); - } - // 预留返回值空间 - fprintf(fp, "\tsub $sp %d\n", func->type->width); - // 调用函数 - fprintf(fp, "\tcall %s\n", func->word.c_str()); - // 释放返回值空间 - fprintf(fp, "\tadd $sp %d\n", func->type->width); - // 参数出栈 + // 传递参数 reverse(args.begin(), args.end()); for (iter = args.begin(); iter != args.end(); iter++){ - fprintf(fp, "\tpop $%d\n", (*iter)->label); + fprintf(fp, "\tparam $%d\n", (*iter)->label); } - // 出栈 - fprintf(fp, "\tload $sp $bp\n"); - fprintf(fp, "\tpop $bp\n"); + // 调用语句 + fprintf(fp, "\tcall %s %d\n", func->word.c_str(), args.size()); } }; @@ -422,15 +416,17 @@ struct Global :Node{ Node::code(fp); if (!ids.empty()){ int width = 0; + fprintf(fp, ".data\n"); list::iterator iter; for (iter = ids.begin(); iter != ids.end(); iter++){ (*iter)->offset = width; (*iter)->global = true; + fprintf(fp, "\t%s %s\n", (*iter)->t->word.c_str(), (*iter)->s->word.c_str()); width += (*iter)->t->width; } - fprintf(fp, ".data %d\n", width); - fprintf(fp, ".stack 1000\n"); } + fprintf(fp, ".stack\n"); + fprintf(fp, "\t\db dup(0x1000)\n"); if (!funcs.empty()){ fprintf(fp, ".code\n"); list::iterator iter2; diff --git a/Parser/lexer.h b/Parser/lexer.h index 5f5a212..b014b0e 100644 --- a/Parser/lexer.h +++ b/Parser/lexer.h @@ -78,8 +78,8 @@ struct Type :Word{ } }; -Type* Type::Int = new Type(BASIC, "int", 2); -Type* Type::Char = new Type(BASIC, "char", 1); +Type* Type::Int = new Type(BASIC, "dw", 2); +Type* Type::Char = new Type(BASIC, "db", 1); Type* Type::Void = new Type(BASIC, "void", 0); struct Integer :Token{ From a3e5da9e4156a8b6050d5232af5c69f2c09485b3 Mon Sep 17 00:00:00 2001 From: mbs0221 Date: Tue, 19 Feb 2019 16:33:32 +0800 Subject: [PATCH 13/22] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20=09new=20file:=20=20?= =?UTF-8?q?=20Asm/inst.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Asm/inst.h | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 Asm/inst.h diff --git a/Asm/inst.h b/Asm/inst.h new file mode 100644 index 0000000..0050502 --- /dev/null +++ b/Asm/inst.h @@ -0,0 +1,236 @@ +#pragma once + +typedef char S1; +typedef short int S2; +typedef int S4; +typedef long int S8; + +typedef unsigned char U1; +typedef unsigned short int U2; +typedef unsigned int U4; +typedef unsigned long int U8; + +typedef float F4; +typedef double F8; + +// 指令集 +enum Inst { + LBI, LWI, LDI, LQI, LF1I, LF2I, + LAD, LAI, + LB, LW, LD, LQ, LF1, LF2, + SB, SW, SD, SQ, SF1, SF2, + PUSHB, PUSHW, PUSHD, PUSHQ, PUSHF1, PUSHF2, + POPB, POPW, POPD, POPQ, POPF1, POPF2, + MOV, MOVF, MOVD, + JMP, JE, JNE, SLT, INT, DI, EI, HALT, NOP, + AND, OR, XOR, NOT, BT, BS, + SRA, SRL, SL, + ADD, SUB, MUL, DIV, + CAST_IF, CAST_ID, CAST_FI, CAST_FD, CAST_DI, CAST_DF, + FADD, FSUB, FMUL, FDIV, FSLT, + DADD, DSUB, DMUL, DDIV, DSLT +}; + +// Load + +#define EXEC_LBI(); R[RAM[IP+1]]=(S1)RAM[IP+2];\ + IP+=3; + +#define EXEC_LWI(); R[RAM[IP+1]]=(S2)*((S2*)&RAM[IP+2]);\ + IP+=4; + +#define EXEC_LDI(); R[RAM[IP+1]]=(S4)*((S4*)&RAM[IP+2]);\ + IP+=6; + +#define EXEC_LQI(); R[RAM[IP+1]]=(S8)*((S8*)&RAM[IP+2]);\ + IP+=10; + +#define EXEC_LF1I(); RF[RAM[IP+1]]=(F4)*((F4*)&RAM[IP+2]);\ + IP+=6; + +#define EXEC_LF2I(); RF[RAM[IP+1]]=(F8)*((F8*)&RAM[IP+2]);\ + IP+=10; + +#define EXEC_LAD(); R[RAM[IP+1]]=(U8)*((U8*)&RAM[IP+2]);\ + IP+=10; + +#define EXEC_LAI(); R[RAM[IP+1]]=R[RAM[IP+2]]+((S8)*((S8*)&RAM[IP+3]));\ + IP+=11; + +#define EXEC_LB(); R[RAM[IP+1]]=(S8)(*((S1*)&RAM[R[RAM[IP+2]]]));\ + IP+=3; + +#define EXEC_LW(); R[RAM[IP+1]]=(S8)(*((S2*)&RAM[(U8)R[RAM[IP+2]]]));\ + IP+=3; + +#define EXEC_LD(); R[RAM[IP+1]]=(S8)(*((S4*)&RAM[(U8)R[RAM[IP+2]]]));\ + IP+=3; + +#define EXEC_LQ(); R[RAM[IP+1]]=(S8)(*((S8*)&RAM[(U8)R[RAM[IP+2]]]));\ + IP+=3; + +#define EXEC_LF1(); RF[RAM[IP+1]]=*((F4*)&RAM[(U8)R[RAM[IP+2]]]);\ + IP+=3; + +#define EXEC_LF2(); RD[RAM[IP+1]]=*((F8*)&RAM[(U8)R[RAM[IP+2]]]);\ + IP+=3; + +// Store + +#define EXEC_SB(); RAM[R[RAM[IP+2]]]=(S1)R[RAM[IP+1]];\ + IP+=3; + +#define EXEC_SW(); *((S2*)&RAM[R[RAM[IP+2]]])=(S2)R[RAM[IP+1]];\ + IP+=3; + +#define EXEC_SD(); *((S4*)&RAM[R[RAM[IP+2]]])=(S4)R[RAM[IP+1]];\ + IP+=3; + +#define EXEC_SQ(); *((S8*)&RAM[R[RAM[IP+2]]])=(S8)R[RAM[IP+1]];\ + IP+=3; + +#define EXEC_SF1(); *((F4*)&RAM[R[RAM[IP+2]]])=RF[RAM[IP+1]];\ + IP+=3; + +#define EXEC_SF2(); *((F8*)&RAM[R[RAM[IP+2]]])=RD[RAM[IP+1]];\ + IP+=3; + +// Push + +#define EXEC_PUSHB(); SP--;\ + RAM[SP]=(S1)(R[RAM[IP+1]]);\ + IP+=2; + +#define EXEC_PUSHW(); SP-=2;\ + *((S2*)&RAM[SP])=(S2)(R[RAM[IP+1]]);\ + IP+=2; + +#define EXEC_PUSHD(); SP-=4;\ + *((S4*)&RAM[SP])=(S4)(R[RAM[IP+1]]);\ + IP+=2; + +#define EXEC_PUSHQ(); SP-=8;\ + *((S8*)&RAM[SP])=(S8)(R[RAM[IP+1]]);\ + IP+=2; + +#define EXEC_PUSHF1(); SP-=4;\ + *((F4*)&RAM[SP])=(F4)(RF[RAM[IP+1]]);\ + IP+=2; + +#define EXEC_PUSHF2(); SP-=8;\ + *((F8*)&RAM[SP])=(F8)(RF[RAM[IP+1]]);\ + IP+=2; + +// Pop + +#define EXEC_POPB(); R[RAM[IP+1]]=(S1)*((S1*)&RAM[SP]);\ + SP+=1;\ + IP+=2; + +#define EXEC_POPW(); R[RAM[IP+1]]=(S2)*((S2*)&RAM[SP]);\ + SP+=2;\ + IP+=2; + +#define EXEC_POPD(); R[RAM[IP+1]]=(S4)*((S4*)&RAM[SP]);\ + SP+=4;\ + IP+=2; + +#define EXEC_POPQ(); R[RAM[IP+1]]=(S8)*((S8*)&RAM[SP]);\ + SP+=8;\ + IP+=2; + +#define EXEC_POPF1(); RF[RAM[IP+1]]=(F4)*((F4*)&RAM[SP]);\ + SP+=4;\ + IP+=2; + +#define EXEC_POPF2(); RD[RAM[IP+1]]=(F8)*((F8*)&RAM[SP]);\ + SP+=8;\ + IP+=2; + +// Mov + +#define EXEC_MOV(); R[RAM[IP+1]]=R[RAM[IP+2]];\ + IP+=3; + +#define EXEC_MOVF(); RF[RAM[IP+1]]=RF[RAM[IP+2]];\ + IP+=3; + +#define EXEC_MOVD(); RD[RAM[IP+1]]=RD[RAM[IP+2]];\ + IP+=3; + +// Jump + +#define EXEC_JMP(); IP=R[RAM[IP+1]]; + +#define EXEC_JE(); if(R[RAM[IP+1]]==R[RAM[IP+2]])\ + IP=R[RAM[IP+3]];\ + else\ + IP+=4; + +#define EXEC_JNE(); if(R[RAM[IP+1]]!=R[RAM[IP+2]])\ + IP=R[RAM[IP+3]];\ + else\ + IP+=4; + +#define EXEC_SLT(); if(R[RAM[IP+2]]> ((S8)R[RAM[IP+3]]);\ + IP+=4; + +#define EXEC_SRL(); R[RAM[IP+1]]=R[RAM[IP+2]] >> R[RAM[IP+3]];\ + IP+=4; + +#define EXEC_SL(); R[RAM[IP+1]]=R[RAM[IP+2]] << R[RAM[IP+3]];\ + IP+=4; + +// Integer Math + +#define EXEC_ADD(); R[RAM[IP+1]]=((S8)R[RAM[IP+2]]) + ((S8)R[RAM[IP+3]]);\ + IP+=4; + +#define EXEC_SUB(); R[RAM[IP+1]]=((S8)R[RAM[IP+2]]) - ((S8)R[RAM[IP+3]]);\ + IP+=4; + +#define EXEC_MUL(); R[RAM[IP+1]]=((S8)R[RAM[IP+2]]) * ((S8)R[RAM[IP+3]]);\ + IP+=4; + +#define EXEC_DIV(); R[RAM[IP+1]]=((S8)R[RAM[IP+3]]) / ((S8)R[RAM[IP+4]]);\ + R[RAM[IP+2]]=((S8)R[RAM[IP+3]]) % ((S8)R[RAM[IP+4]]);\ + IP+=5; \ No newline at end of file From 0a20cf737078431b6b9a6ff83de04a45cbd960e6 Mon Sep 17 00:00:00 2001 From: mbs0221 Date: Tue, 10 Sep 2019 10:27:04 +0800 Subject: [PATCH 14/22] update project --- .gitignore | 2 + Asm/Asm.vcxproj | 5 +- Asm/Asm.vcxproj.filters | 100 +++++++++++++++++----------------- CPU/CPU.vcxproj | 5 +- CPU/CPU.vcxproj.filters | 58 ++++++++++---------- Parser/Parser.vcxproj | 5 +- Parser/Parser.vcxproj.filters | 96 ++++++++++++++++---------------- 7 files changed, 138 insertions(+), 133 deletions(-) diff --git a/.gitignore b/.gitignore index 1bc915c..0dd1a26 100644 --- a/.gitignore +++ b/.gitignore @@ -154,3 +154,5 @@ $RECYCLE.BIN/ # Mac desktop service store files .DS_Store +/VM.VC.VC.opendb +/VM.VC.db diff --git a/Asm/Asm.vcxproj b/Asm/Asm.vcxproj index 2a63871..b1fa5e6 100644 --- a/Asm/Asm.vcxproj +++ b/Asm/Asm.vcxproj @@ -13,18 +13,19 @@ {02E49534-A118-4FF8-8114-F3F5FA873223} Asm + 8.1 Application true - v120 + v140 MultiByte Application false - v120 + v140 true MultiByte diff --git a/Asm/Asm.vcxproj.filters b/Asm/Asm.vcxproj.filters index cc6a5e0..800f3e4 100644 --- a/Asm/Asm.vcxproj.filters +++ b/Asm/Asm.vcxproj.filters @@ -1,51 +1,51 @@ -锘 - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - 澶存枃浠 - - - 澶存枃浠 - - - 澶存枃浠 - - - 澶存枃浠 - - - 澶存枃浠 - - - - - 婧愭枃浠 - - - 婧愭枃浠 - - - - - 璧勬簮鏂囦欢 - - - - 璧勬簮鏂囦欢 - - +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + + + 婧愭枃浠 + + + 婧愭枃浠 + + + + + 璧勬簮鏂囦欢 + + + + 璧勬簮鏂囦欢 + + \ No newline at end of file diff --git a/CPU/CPU.vcxproj b/CPU/CPU.vcxproj index 20c010c..c4dc528 100644 --- a/CPU/CPU.vcxproj +++ b/CPU/CPU.vcxproj @@ -20,18 +20,19 @@ {9C3738FC-3CCD-4F28-ACB3-BDB310F2C523} CPU + 8.1 Application true - v120 + v140 MultiByte Application false - v120 + v140 true MultiByte diff --git a/CPU/CPU.vcxproj.filters b/CPU/CPU.vcxproj.filters index c20d9ac..223971e 100644 --- a/CPU/CPU.vcxproj.filters +++ b/CPU/CPU.vcxproj.filters @@ -1,30 +1,30 @@ -锘 - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - 婧愭枃浠 - - - 婧愭枃浠 - - - - - 澶存枃浠 - - +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + 婧愭枃浠 + + + + + 澶存枃浠 + + \ No newline at end of file diff --git a/Parser/Parser.vcxproj b/Parser/Parser.vcxproj index 9103717..5a64c7e 100644 --- a/Parser/Parser.vcxproj +++ b/Parser/Parser.vcxproj @@ -13,18 +13,19 @@ {CF29041C-7B18-4A25-B28C-2660CAFD81F6} Parser + 8.1 Application true - v120 + v140 MultiByte Application false - v120 + v140 true MultiByte diff --git a/Parser/Parser.vcxproj.filters b/Parser/Parser.vcxproj.filters index f55bc75..925c5c2 100644 --- a/Parser/Parser.vcxproj.filters +++ b/Parser/Parser.vcxproj.filters @@ -1,49 +1,49 @@ -锘 - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - 璧勬簮鏂囦欢 - - - - - 婧愭枃浠 - - - - - 澶存枃浠 - - - 澶存枃浠 - - - 澶存枃浠 - - - 澶存枃浠 - - - 璧勬簮鏂囦欢 - - - - - 璧勬簮鏂囦欢 - - +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 璧勬簮鏂囦欢 + + + + + 婧愭枃浠 + + + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 璧勬簮鏂囦欢 + + + + + 璧勬簮鏂囦欢 + + \ No newline at end of file From e155c7f14d790a6f7b418987dd4794a5082ef33e Mon Sep 17 00:00:00 2001 From: mbs0221 Date: Tue, 10 Sep 2019 10:58:44 +0800 Subject: [PATCH 15/22] add exception handling --- Parser/Parser.vcxproj.filters | 10 +++++----- Parser/inter.h | 33 +++++++++++++++++++++++++++++++++ Parser/lexer.h | 31 +++++++++++++------------------ Parser/main.cpp | 4 +--- Parser/parser.h | 22 ++++++++++++++++++++++ 5 files changed, 74 insertions(+), 26 deletions(-) diff --git a/Parser/Parser.vcxproj.filters b/Parser/Parser.vcxproj.filters index 925c5c2..158a7f2 100644 --- a/Parser/Parser.vcxproj.filters +++ b/Parser/Parser.vcxproj.filters @@ -19,11 +19,6 @@ 璧勬簮鏂囦欢 - - - 婧愭枃浠 - - 澶存枃浠 @@ -46,4 +41,9 @@ 璧勬簮鏂囦欢 + + + 婧愭枃浠 + + \ No newline at end of file diff --git a/Parser/inter.h b/Parser/inter.h index d3c18f9..1c32d2a 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -328,6 +328,39 @@ struct Continue :Stmt{ stack Continue::cur = stack(); +// 异常处理程序 +struct Throw : Stmt { + Type* exception;// 抛出异常 + Throw() { + exception = nullptr; + } + virtual void code(FILE *fp) { + Stmt::code(fp); + // 跳转异常处理程序 + fprintf(fp, "\tjmp L%d\n", exception->kind); + } +}; + +struct TryCatch : Stmt{ + Stmt *pTry, *pCatch, *pFinnaly; + TryCatch() { + pTry = pCatch = pFinnaly = nullptr; + } + virtual void code(FILE *fp) { + Stmt::code(fp); + // 需要异常处理的程序 + pTry->code(fp); + fprintf(fp, "\tjmp L%d\n", pCatch->next); + // 异常处理程序 + fprintf(fp, "L%d:\n", pCatch->begin); + pCatch->code(fp); + fprintf(fp, "L%d:\n", pCatch->next); + // 扫尾操作 + pFinnaly->code(fp); + } +}; + +// 符号表 struct Symbols{ int id; static int count; diff --git a/Parser/lexer.h b/Parser/lexer.h index b014b0e..b8bbb0c 100644 --- a/Parser/lexer.h +++ b/Parser/lexer.h @@ -13,7 +13,7 @@ using namespace std; enum Tag{ - IF = 256, THEN, ELSE, DO, WHILE, FOR, CASE, BREAK, CONTINUE, + IF = 256, THEN, ELSE, DO, WHILE, FOR, CASE, BREAK, CONTINUE, TRY, CATCH, FINALLY, THROW, BASIC, INT, CHAR, END, ID, NUM, FUNCTION @@ -30,23 +30,17 @@ struct Token{ } virtual string code(){ ostringstream s; - switch (kind){ - case IF:s << "IF"; break; - case THEN:s << "THEN"; break; - case ELSE:s << "ELSE"; break; - case DO:s << "DO"; break; - case WHILE:s << "WHILE"; break; - case FOR:s << "FOR"; break; - case CASE:s << "CASE"; break; - case BREAK:s << "BREAK"; break; - case CONTINUE:s << "CONTINUE"; break; - case ID:s << "ID"; break; - case BASIC:s << "BASIC"; break; - case INT:s << "INT"; break; - case CHAR:s << "CHAR"; break; - case END:s << "END"; break; - default:s << (char)kind; break; - } + char *keywords[] = { + "IF", "THEN", "ELSE", + "DO", "WHILE", "FOR", + "CASE", "BREAK", "CONTINUE", + "TRY", "CATCH", "FINALLY", "THROW", + "ID", "BASIC", "INT", "CHAR", "END" + }; + if (kind >=IF && kind <= END) + s << keywords[kind]; + else + s << (char)kind; return s.str(); } }; @@ -115,6 +109,7 @@ class Lexer{ words["break"] = new Word(BREAK, "break"); words["continue"] = new Word(CONTINUE, "continue"); words["end"] = new Word(END, "end"); + words["try"] = new Word(TRY, "try"); inf.open(fp, ios::in); } ~Lexer(){ diff --git a/Parser/main.cpp b/Parser/main.cpp index 17552b2..779b345 100644 --- a/Parser/main.cpp +++ b/Parser/main.cpp @@ -21,6 +21,4 @@ void main(){ //printf("SLR(1)语法分析结束\n"); //fclose(fp); cin >> a; -} - - +} \ No newline at end of file diff --git a/Parser/parser.h b/Parser/parser.h index ac3fffb..b23301e 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -36,6 +36,7 @@ class Parser{ printf("[%d] %s undeclared.\n", lexer->line, ((Word*)s)->word.c_str()); return nullptr; } +protected: // 外部结构 void node(){ while (s->kind == BASIC){ @@ -119,6 +120,7 @@ class Parser{ case CASE:st = stmt_case(); break; case BREAK:st = stmt_break(); break; case CONTINUE:st = stmt_continue(); break; + case TRY:st = stmt_try(); break; case ';':match(';'); break; case '{':st = stmts(); break; default:match(s->kind); break; @@ -144,6 +146,7 @@ class Parser{ symbols = symbols->prev; return sts; } + // 定义 Stmt* stmt_decl(){ Decl *d = new Decl; d->line = lexer->line; @@ -159,6 +162,7 @@ class Parser{ match(';'); return d; } + // 赋值 Stmt* stmt_assign(){ Assign *a = new Assign; a->line = lexer->line; @@ -168,6 +172,7 @@ class Parser{ a->E2 = expr_expr(); return a; } + // 条件语句 Stmt* stmt_if(){ If *i = new If; i->line = lexer->line; @@ -187,6 +192,7 @@ class Parser{ } return i; } + // 循环语句 Stmt* stmt_while(){ While *w = new While; w->line = lexer->line; @@ -235,6 +241,7 @@ class Parser{ Break::cur.pop(); return f; } + // 分支语句 Stmt* stmt_case(){ Case *c = new Case; c->line = lexer->line; @@ -263,6 +270,20 @@ class Parser{ match(';'); return st; } + // 异常处理 + Stmt* stmt_throw() { + match(THROW); + } + Stmt* stmt_try() { + TryCatch *st = new TryCatch(); + match(TRY); + st->pTry = stmt(); + match(CATCH); + st->pCatch = stmt(); + match(FINALLY); + st->pFinnaly = stmt(); + } + // 表达式语句 Cond* expr_cond() { Expr* e = expr_expr(); @@ -327,6 +348,7 @@ class Parser{ } return e; } + // 函数调用 Expr* expr_call(){ Call *c = new Call; c->line = lexer->line; From a83638d353d33c59d46a6f25aab32f4543440af5 Mon Sep 17 00:00:00 2001 From: mbs0221 Date: Tue, 10 Sep 2019 20:02:56 +0800 Subject: [PATCH 16/22] update --- Parser/inter.h | 12 ++++++------ Parser/lexer.h | 3 +++ Parser/parser.h | 1 + 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Parser/inter.h b/Parser/inter.h index 1c32d2a..18a4942 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -74,11 +74,11 @@ struct Cond :Expr{ E2->code(fp); fprintf(fp, "\t%c $%d $%d $%d\n", opt, E1->label, E2->label, label); switch (opt){ - case '>':fprintf(fp, "\tjg L%d\n", True); break; - case '=':fprintf(fp, "\tje L%d\n", True); break; - case '<':fprintf(fp, "\tjb L%d\n", True); break; - case '!':fprintf(fp, "\tjne L%d\n", True); break; - default:fprintf(fp, "\tjmp L%d\n", True); break; + case '>':fprintf(fp, "\tgt L%d\n", True); break; + case '=':fprintf(fp, "\teq L%d\n", True); break; + case '<':fprintf(fp, "\tlt L%d\n", True); break; + case '!':fprintf(fp, "\tneq L%d\n", True); break; + default: fprintf(fp, "\ttmp L%d\n", True); break; } fprintf(fp, "\tjmp L%d\n", False); } @@ -132,7 +132,7 @@ struct Id :Expr{ } }; -struct Number :Expr{ +struct Number : Expr{ Integer *s; Number(Integer *s) :Expr('@'), s(s){ } virtual void code(FILE *fp){ diff --git a/Parser/lexer.h b/Parser/lexer.h index b8bbb0c..7dd8ce4 100644 --- a/Parser/lexer.h +++ b/Parser/lexer.h @@ -110,6 +110,9 @@ class Lexer{ words["continue"] = new Word(CONTINUE, "continue"); words["end"] = new Word(END, "end"); words["try"] = new Word(TRY, "try"); + words["catch"] = new Word(CATCH, "catch"); + words["finally"] = new Word(FINALLY, "finally"); + words["throw"] = new Word(THROW, "throw"); inf.open(fp, ios::in); } ~Lexer(){ diff --git a/Parser/parser.h b/Parser/parser.h index b23301e..ba548cd 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -282,6 +282,7 @@ class Parser{ st->pCatch = stmt(); match(FINALLY); st->pFinnaly = stmt(); + return st; } // 表达式语句 Cond* expr_cond() From a7ca824843d0070a3e615665e3575ad1f10ad5f0 Mon Sep 17 00:00:00 2001 From: mbs0221 Date: Thu, 12 Sep 2019 21:34:45 +0800 Subject: [PATCH 17/22] update project --- Parser/inter.h | 71 +++++++++++++++++------------ Parser/lexer.h | 119 +++++++++++++++++++++++++++--------------------- Parser/parser.h | 118 +++++++++++++++++++++++++++++++---------------- 3 files changed, 188 insertions(+), 120 deletions(-) diff --git a/Parser/inter.h b/Parser/inter.h index 18a4942..0dd6668 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -8,6 +8,7 @@ struct Node{ virtual void code(FILE *fp){ + } }; @@ -52,10 +53,10 @@ struct Stmts :Stmt{ //表达式 struct Expr :Stmt{ - char opt; + string opt; int label; static int count; - Expr(char opt) :opt(opt){ label = count++; } + Expr(string opt) :opt(opt){ label = count++; } virtual void code(FILE *fp){ Node::code(fp); } @@ -63,23 +64,35 @@ struct Expr :Stmt{ int Expr::count = 0; +// 双目表达式 +struct BinaryExpr : Expr { + Expr *pL, *pR; + BinaryExpr(string opt, Expr *pL, Expr *pR) : Expr(opt), pL(pL), pR(pR) { ; } + virtual void code(FILE *fp) override { + Expr::code(fp); + pL->code(fp); + pR->code(fp); + fprintf(fp, "\t%c $%d $%d $%d\n", opt, pL->label, pR->label, label); + } +}; + // 条件表达式 -struct Cond :Expr{ +struct Cond : Expr{ int True, False; Expr *E1, *E2; - Cond(char opt, Expr *E1, Expr *E2) :Expr(opt), E1(E1), E2(E2){} + Cond(string opt, Expr *E1, Expr *E2) :Expr(opt), E1(E1), E2(E2){} virtual void code(FILE *fp){ Expr::code(fp); E1->code(fp); E2->code(fp); fprintf(fp, "\t%c $%d $%d $%d\n", opt, E1->label, E2->label, label); - switch (opt){ - case '>':fprintf(fp, "\tgt L%d\n", True); break; - case '=':fprintf(fp, "\teq L%d\n", True); break; - case '<':fprintf(fp, "\tlt L%d\n", True); break; - case '!':fprintf(fp, "\tneq L%d\n", True); break; - default: fprintf(fp, "\ttmp L%d\n", True); break; - } + //switch (opt){ + //case '>':fprintf(fp, "\tgt L%d\n", True); break; + //case '=':fprintf(fp, "\teq L%d\n", True); break; + //case '<':fprintf(fp, "\tlt L%d\n", True); break; + //case '!':fprintf(fp, "\tneq L%d\n", True); break; + //default: fprintf(fp, "\ttmp L%d\n", True); break; + //} fprintf(fp, "\tjmp L%d\n", False); } }; @@ -87,26 +100,27 @@ struct Cond :Expr{ // 算术表达式 struct Arith :Expr{ Expr *E1, *E2; - Arith(char opt, Expr *E1, Expr *E2) :Expr(opt), E1(E1), E2(E2){} + Arith(string opt, Expr *E1, Expr *E2) :Expr(opt), E1(E1), E2(E2){} virtual void code(FILE *fp){ Expr::code(fp); E1->code(fp); E2->code(fp); - switch (opt){ - case '+':fprintf(fp, "\tadd "); break; - case '-':fprintf(fp, "\tsub "); break; - case '*':fprintf(fp, "\tmul "); break; - case '/':fprintf(fp, "\tdiv "); break; - case '&':fprintf(fp, "\tand "); break; - default:break; - } + //switch (opt){ + //case '+':fprintf(fp, "\tadd "); break; + //case '-':fprintf(fp, "\tsub "); break; + //case '*':fprintf(fp, "\tmul "); break; + //case '/':fprintf(fp, "\tdiv "); break; + //case '&':fprintf(fp, "\tand "); break; + //default:break; + //} fprintf(fp, "$%d $%d $%d\n", E1->label, E2->label, label); } }; -struct Unary :Expr{ +// 单目表达式 +struct UnaryExpr :Expr{ Expr *E1; - Unary(char opt, Expr *E1) :Expr(opt), E1(E1){ } + UnaryExpr(string opt, Expr *E1) :Expr(opt), E1(E1){ } virtual void code(FILE *fp){ Expr::code(fp); E1->code(fp); @@ -120,7 +134,7 @@ struct Id :Expr{ Word *s; int offset; bool global; - Id(Type *t, Word *s) :Expr('@'), t(t), s(s){ } + Id(Type *t, Word *s) :Expr("@"), t(t), s(s){ } virtual void code(FILE *fp){ Expr::code(fp); char width = t == Type::Int ? 'w' : 'b'; @@ -134,7 +148,7 @@ struct Id :Expr{ struct Number : Expr{ Integer *s; - Number(Integer *s) :Expr('@'), s(s){ } + Number(Integer *s) :Expr("@"), s(s){ } virtual void code(FILE *fp){ Expr::code(fp); char width = s->value > 256 ? 'w' : 'b'; @@ -342,10 +356,11 @@ struct Throw : Stmt { }; struct TryCatch : Stmt{ - Stmt *pTry, *pCatch, *pFinnaly; + Stmt *pTry, *pCatch, *pFinally; TryCatch() { - pTry = pCatch = pFinnaly = nullptr; + pTry = pCatch = pFinally = nullptr; } + TryCatch(Stmt* pTry, Stmt* pCatch, Stmt* pFinally) :pTry(pTry), pCatch(pCatch), pFinally(pFinally) { } virtual void code(FILE *fp) { Stmt::code(fp); // 需要异常处理的程序 @@ -356,7 +371,7 @@ struct TryCatch : Stmt{ pCatch->code(fp); fprintf(fp, "L%d:\n", pCatch->next); // 扫尾操作 - pFinnaly->code(fp); + pFinally->code(fp); } }; @@ -423,7 +438,7 @@ struct Function : Word{ struct Call :Expr{ list args; Function *func; - Call() :Expr('@'){ args.clear(); } + Call() :Expr("@"){ args.clear(); } virtual void code(FILE *fp){ Stmt::code(fp); printf("call\n"); diff --git a/Parser/lexer.h b/Parser/lexer.h index 7dd8ce4..2c1566e 100644 --- a/Parser/lexer.h +++ b/Parser/lexer.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -14,9 +15,17 @@ using namespace std; enum Tag{ IF = 256, THEN, ELSE, DO, WHILE, FOR, CASE, BREAK, CONTINUE, TRY, CATCH, FINALLY, THROW, - BASIC, INT, CHAR, + BASIC, INT, CHAR, END, - ID, NUM, FUNCTION + ID, NUM, FUNCTION, + AND, OR, NOT, // LOGIC + BIT_AND, BIT_OR, BIT_NOT, // BIT LOGIC + EQ, NEQ, // REL + LT, LEQ, GEQ, GT, // REL + SHL, SHR, // SHIFT + ADD, SUB, // TERM + MUL, DIV, // FACTOR + INC, DEC // UNARY }; // 词法单元 @@ -31,14 +40,13 @@ struct Token{ virtual string code(){ ostringstream s; char *keywords[] = { - "IF", "THEN", "ELSE", - "DO", "WHILE", "FOR", + "IF", "THEN", "ELSE", "DO", "WHILE", "FOR", "CASE", "BREAK", "CONTINUE", "TRY", "CATCH", "FINALLY", "THROW", "ID", "BASIC", "INT", "CHAR", "END" }; if (kind >=IF && kind <= END) - s << keywords[kind]; + s << keywords[kind - IF]; else s << (char)kind; return s.str(); @@ -119,6 +127,57 @@ class Lexer{ inf.close(); words.clear(); printf("~Lexer\n"); + } + Integer* match_integer(char ch) { + int value = 0; + if (ch == '0') { + inf.read(&ch, sizeof(ch)); + if (ch == 'x' || ch == 'X') { + inf.read(&ch, sizeof(ch)); + if (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')) { + do { + if (isalpha(ch)) { + value = 16 * value + ch - 'A' + 10; + } + else { + value = 16 * value + ch - '0'; + } + inf.read(&ch, sizeof(ch)); + } while (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')); + inf.seekg(-1, ios::cur); + return new Integer(NUM, value); + } + else { + printf("错误的十六进制!"); + } + } + else if (ch >= '0'&&ch <= '7') { + //八进制整数 + do { + value = 8 * value + ch - '0'; + inf.read(&ch, sizeof(ch)); + } while (ch >= '0'&&ch <= '7'); + inf.seekg(-1, ios::cur); + return new Integer(NUM, value); + } + else { + //十进制整数0 + inf.seekg(-1, ios::cur); + return new Integer(NUM, 0); + } + } + else { + //除0外十进制整数,5状态 + do { + value = 10 * value + ch - '0'; + inf.read(&ch, sizeof(ch)); + } while (isdigit(ch)); + inf.seekg(-1, ios::cur);//回退一个字符 + return new Integer(NUM, value); + } + } + void match_operator(char ch) { + } Token *scan() { @@ -136,7 +195,7 @@ class Lexer{ do{ str.push_back(ch); inf.read(&ch, sizeof(ch)); - } while (isalnum(ch)); //1状态 + } while (isalnum(ch) || ch == '_'); //1状态 inf.seekg(-1, ios::cur);//回退一个字符 if (words.find(str) == words.end()){ return new Word(ID, str); @@ -144,53 +203,9 @@ class Lexer{ return words[str]; } if (isdigit(ch)){ - int value = 0; - if (ch == '0'){ - inf.read(&ch, sizeof(ch)); - if (ch == 'x' || ch == 'X'){ - inf.read(&ch, sizeof(ch)); - if (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')){ - do{ - if (isalpha(ch)){ - value = 16 * value + ch - 'A' + 10; - } - else{ - value = 16 * value + ch - '0'; - } - inf.read(&ch, sizeof(ch)); - } while (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')); - inf.seekg(-1, ios::cur); - return new Integer(NUM, value); - } - else{ - printf("错误的十六进制!"); - } - } - else if (ch >= '0'&&ch <= '7'){ - //八进制整数 - do{ - value = 8 * value + ch - '0'; - inf.read(&ch, sizeof(ch)); - } while (ch >= '0'&&ch <= '7'); - inf.seekg(-1, ios::cur); - return new Integer(NUM, value); - } - else{ - //十进制整数0 - inf.seekg(-1, ios::cur); - return new Integer(NUM, 0); - } - } - else{ - //除0外十进制整数,5状态 - do{ - value = 10 * value + ch - '0'; - inf.read(&ch, sizeof(ch)); - } while (isdigit(ch)); - inf.seekg(-1, ios::cur);//回退一个字符 - return new Integer(NUM, value); - } + return match_integer(ch); } + return new Token(ch); } }; diff --git a/Parser/parser.h b/Parser/parser.h index ba548cd..c449f28 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -22,6 +22,7 @@ class Parser{ printf("%s not matched.\n", kind); return false; } + map precedence; // 符号表管理 Id* getId(){ list::iterator iter; @@ -36,6 +37,29 @@ class Parser{ printf("[%d] %s undeclared.\n", lexer->line, ((Word*)s)->word.c_str()); return nullptr; } + void init_precedence() { + precedence["*"] = 3; // term + precedence["/"] = 3; + precedence["%"] = 3; + precedence["+"] = 4; // expr + precedence["-"] = 4; + precedence["<<"] = 5; // shift + precedence[">>"] = 5; + precedence["<"] = 6; // rel + precedence["<="] = 6; + precedence[">="] = 6; + precedence[">"] = 6; + precedence["=="] = 7; // rel + precedence["!="] = 7; + precedence["&"] = 8; // bitop + precedence["^"] = 9; + precedence["|"] = 10; + precedence["&&"] = 11; // logical + precedence["||"] = 12; + } + bool compare(string &opa, string &opb) { + return precedence[opa] > precedence[opb]; + } protected: // 外部结构 void node(){ @@ -275,55 +299,67 @@ class Parser{ match(THROW); } Stmt* stmt_try() { - TryCatch *st = new TryCatch(); match(TRY); - st->pTry = stmt(); + Stmt* pTry = stmt(); match(CATCH); - st->pCatch = stmt(); + Stmt* pCatch = stmt(); match(FINALLY); - st->pFinnaly = stmt(); - return st; + Stmt* pFinnaly = stmt(); + return new TryCatch(pTry, pCatch, pFinnaly); } // 表达式语句 - Cond* expr_cond() - { - Expr* e = expr_expr(); - if (s->kind == '<' || s->kind == '>' || s->kind == '=' || s->kind == '!'){ - char opt = s->kind; - match(s->kind); - Expr *r = expr_expr(); - return new Cond(opt, e, r); - } - return nullptr; - } - Expr* expr_expr() - { - Expr* e = expr_term(); - while (s->kind == '+' || s->kind == '-'){ - char opt = s->kind; - match(s->kind); - Expr *r = expr_term(); - e = new Arith(opt, e, r); + BinaryExpr* expr_binary() { + Expr* pL = expr_binary(); + while (s->kind) { + if (compare(s->kind, pL->opt)) { + Expr* pR = expr_binary(); + } + pL = new BinaryExpr(opt, pL, pR); } - return e; + return pL; } - Expr* expr_term() - { - Expr* e = expr_unary(); - while (s->kind == '*' || s->kind == '/' || s->kind == '%') - { - char opt = s->kind; - match(s->kind); - Expr *r = expr_unary(); - e = new Arith(opt, e, r); - } - return e; + UnaryExpr* expr_unary() { + match('-'); } - Expr* expr_unary(){ + //Cond* expr_cond() + //{ + // Expr* e = expr_expr(); + // if (s->kind == '<' || s->kind == '>' || s->kind == '=' || s->kind == '!'){ + // char opt = s->kind; + // match(s->kind); + // Expr *r = expr_expr(); + // return new Cond(opt, e, r); + // } + // return nullptr; + //} + //Expr* expr_expr() + //{ + // Expr* e = expr_term(); + // while (s->kind == '+' || s->kind == '-'){ + // char opt = s->kind; + // match(s->kind); + // Expr *r = expr_term(); + // e = new Arith(opt, e, r); + // } + // return e; + //} + //Expr* expr_term() + //{ + // Expr* e = expr_unary(); + // while (s->kind == '*' || s->kind == '/' || s->kind == '%') + // { + // string opt(s->kind); + // match(s->kind); + // Expr *r = expr_unary(); + // e = new Arith(opt, e, r); + // } + // return e; + //} + UnaryExpr* expr_unary(){ Expr *u; if (s->kind == '~'){ match('~'); - u = new Unary('~', expr_unary()); + u = new UnaryExpr("~", expr_unary()); } else{ u = expr_factor(); @@ -334,7 +370,7 @@ class Parser{ { Expr* e = nullptr; switch (s->kind){ - case '(': match('('); e = expr_expr(); match(')'); break; + case '(': match('('); e = expr_binary(); match(')'); break; case ID: { switch (getId()->s->kind){ @@ -358,7 +394,7 @@ class Parser{ // 函数调用 match('('); while (s->kind == ID || s->kind == NUM){ - Expr *e = expr_expr(); + Expr *e = expr_binary(); if (e)c->args.push_back(e); if (s->kind == ',') match(','); } @@ -367,12 +403,14 @@ class Parser{ } public: Parser(string fp){ + init_precedence(); lexer = new Lexer(fp); symbols = new Symbols(); globol = new Global(); } ~Parser(){ printf("~Parser\n"); + precedence.clear(); delete lexer; delete symbols; delete globol; From 687b4efd317dbc03dfd3108c5bae49be6365957b Mon Sep 17 00:00:00 2001 From: mbs0221 Date: Fri, 13 Sep 2019 00:17:29 +0800 Subject: [PATCH 18/22] update --- Parser/inter.h | 153 +++++++++++++++++------------------------------- Parser/lexer.h | 142 +++++++++++++++++++++++++++++++++++--------- Parser/main.cpp | 4 +- Parser/parser.h | 81 +++++++++++-------------- 4 files changed, 207 insertions(+), 173 deletions(-) diff --git a/Parser/inter.h b/Parser/inter.h index 0dd6668..b167bb2 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -53,10 +53,9 @@ struct Stmts :Stmt{ //表达式 struct Expr :Stmt{ - string opt; int label; static int count; - Expr(string opt) :opt(opt){ label = count++; } + Expr() { label = count++; } virtual void code(FILE *fp){ Node::code(fp); } @@ -66,61 +65,22 @@ int Expr::count = 0; // 双目表达式 struct BinaryExpr : Expr { + Word opt; Expr *pL, *pR; - BinaryExpr(string opt, Expr *pL, Expr *pR) : Expr(opt), pL(pL), pR(pR) { ; } + BinaryExpr(Word &opt, Expr *pL, Expr *pR) : opt(opt), pL(pL), pR(pR) { ; } virtual void code(FILE *fp) override { Expr::code(fp); pL->code(fp); pR->code(fp); - fprintf(fp, "\t%c $%d $%d $%d\n", opt, pL->label, pR->label, label); - } -}; - -// 条件表达式 -struct Cond : Expr{ - int True, False; - Expr *E1, *E2; - Cond(string opt, Expr *E1, Expr *E2) :Expr(opt), E1(E1), E2(E2){} - virtual void code(FILE *fp){ - Expr::code(fp); - E1->code(fp); - E2->code(fp); - fprintf(fp, "\t%c $%d $%d $%d\n", opt, E1->label, E2->label, label); - //switch (opt){ - //case '>':fprintf(fp, "\tgt L%d\n", True); break; - //case '=':fprintf(fp, "\teq L%d\n", True); break; - //case '<':fprintf(fp, "\tlt L%d\n", True); break; - //case '!':fprintf(fp, "\tneq L%d\n", True); break; - //default: fprintf(fp, "\ttmp L%d\n", True); break; - //} - fprintf(fp, "\tjmp L%d\n", False); - } -}; - -// 算术表达式 -struct Arith :Expr{ - Expr *E1, *E2; - Arith(string opt, Expr *E1, Expr *E2) :Expr(opt), E1(E1), E2(E2){} - virtual void code(FILE *fp){ - Expr::code(fp); - E1->code(fp); - E2->code(fp); - //switch (opt){ - //case '+':fprintf(fp, "\tadd "); break; - //case '-':fprintf(fp, "\tsub "); break; - //case '*':fprintf(fp, "\tmul "); break; - //case '/':fprintf(fp, "\tdiv "); break; - //case '&':fprintf(fp, "\tand "); break; - //default:break; - //} - fprintf(fp, "$%d $%d $%d\n", E1->label, E2->label, label); + fprintf(fp, "\t%c $%d $%d $%d\n", opt.word.c_str(), pL->label, pR->label, label); } }; // 单目表达式 struct UnaryExpr :Expr{ + Word opt; Expr *E1; - UnaryExpr(string opt, Expr *E1) :Expr(opt), E1(E1){ } + UnaryExpr(Word &opt, Expr *E1) :opt(opt), E1(E1){ } virtual void code(FILE *fp){ Expr::code(fp); E1->code(fp); @@ -130,25 +90,29 @@ struct UnaryExpr :Expr{ // ID struct Id :Expr{ - Type *t; - Word *s; + Type *type; + Word *name; int offset; bool global; - Id(Type *t, Word *s) :Expr("@"), t(t), s(s){ } +public: + Id(Type *type, Word *name) : type(type), name(name){ } + const char* getName() { return name->word.c_str(); } + const char* getTypeName() { return type->word.c_str(); } + int getWidth() { return type->width; } virtual void code(FILE *fp){ Expr::code(fp); - char width = t == Type::Int ? 'w' : 'b'; + char *width = type == Type::Int ? "dw" : "b"; if (global){ - fprintf(fp, "\tload%c $%d %s\n", width, label, s->word.c_str()); + fprintf(fp, "\tload%s $%d %s\n", width, label, name->getName()); }else{ - fprintf(fp, "\tload%c $%d %s\n", width, label, s->word.c_str()); + fprintf(fp, "\tload%s $%d %s\n", width, label, name->getName()); } } }; -struct Number : Expr{ +struct Constant : Expr{ Integer *s; - Number(Integer *s) :Expr("@"), s(s){ } + Constant(Integer *s) : s(s){ } virtual void code(FILE *fp){ Expr::code(fp); char width = s->value > 256 ? 'w' : 'b'; @@ -161,14 +125,14 @@ struct Decl :Stmt{ virtual void code(FILE *fp){ Stmt::code(fp); printf("data\n"); - //fprintf(fp, "\tdata\n"); - //list::iterator iter; - //for (iter = ids.begin(); iter != ids.end(); iter++){ - // printf("\t$%s [%d]\n", (*iter)->s->word.c_str(), (*iter)->t->width); - // fprintf(fp, "\t\t$%s [%d]\n", (*iter)->s->word.c_str(), (*iter)->t->width); - //} - //printf("data\n"); - //fprintf(fp, "\tdata\n"); + fprintf(fp, "\tdata\n"); + list::iterator iter; + for (iter = ids.begin(); iter != ids.end(); iter++){ + printf("\t$%s [%d]\n", (*iter)->getName(), (*iter)->getWidth()); + fprintf(fp, "\t\t$%s [%d]\n", (*iter)->getName(), (*iter)->getWidth()); + } + printf("data\n"); + fprintf(fp, "\tdata\n"); } }; @@ -180,65 +144,63 @@ struct Assign :Stmt{ printf("assign\n"); E2->code(fp); if (E1->global){ - fprintf(fp, "\tstore %s $%d\n", E1->s->word.c_str(), E2->label); + fprintf(fp, "\tstore %s $%d\n", E1->getName(), E2->label); }else{ - fprintf(fp, "\tstore %s $%d\n", E1->s->word.c_str(), E2->label); + fprintf(fp, "\tstore %s $%d\n", E1->getName(), E2->label); } } }; struct If :Stmt{ - Cond *C; + Expr *C; Stmt *S1; virtual void code(FILE *fp){ Stmt::code(fp); printf("if\n"); next = newlabel(); - C->True = newlabel(); - C->False = next; S1->next = next; + // 计算表达式 C->code(fp); - fprintf(fp, "L%d:\n", C->True); + // 为False跳转 + fprintf(fp, "jz L%d", next);// False跳转 S1->code(fp); fprintf(fp, "L%d:\n", next); } }; -struct Else :Stmt{ - Cond *C; +struct IfElse :Stmt{ + Expr *C; Stmt *S1; Stmt *S2; virtual void code(FILE *fp){ Stmt::code(fp); printf("if-else\n"); - next = newlabel(); - C->True = newlabel(); - C->False = newlabel(); - S1->next = next; + S1->next = newlabel(); + S2->next = newlabel(); + // 计算表达式 C->code(fp); - fprintf(fp, "L%d:\n", C->True); + // 为False跳转 + fprintf(fp, "jz L%d:\n", next);// False跳转 S1->code(fp); fprintf(fp, "\tjmp L%d\n", next); - fprintf(fp, "L%d:\n", C->False); - S2->code(fp); fprintf(fp, "L%d:\n", next); + S2->code(fp); + fprintf(fp, "L%d:\n", S1->next); } }; struct While :Stmt{ - Cond *C; + Expr *C; Stmt *S1; virtual void code(FILE *fp){ Stmt::code(fp); printf("while\n"); begin = newlabel(); next = newlabel(); - C->True = newlabel(); - C->False = next; S1->next = begin; fprintf(fp, "L%d:\n", begin); C->code(fp); - fprintf(fp, "L%d:\n", C->True); + fprintf(fp, "jz L:\n", next);// False跳转 S1->code(fp); fprintf(fp, "\tjmp L%d\n", begin); fprintf(fp, "L%d:\n", next); @@ -246,26 +208,23 @@ struct While :Stmt{ }; struct Do :Stmt{ - Cond *C; + Expr *C; Stmt *S1; virtual void code(FILE *fp){ Stmt::code(fp); printf("do-while\n"); begin = newlabel(); - next = newlabel(); - C->True = begin; - C->False = next; S1->next = begin; fprintf(fp, "L%d:\n", begin); S1->code(fp); C->code(fp); - fprintf(fp, "L%d:\n", next); + fprintf(fp, "jnz L%d:\n", begin);// True跳转 } }; struct For :Stmt{ Stmt *S1; - Cond *C; + Expr *C; Stmt *S2; Stmt *S3; virtual void code(FILE *fp){ @@ -273,15 +232,13 @@ struct For :Stmt{ printf("for\n"); begin = newlabel(); next = newlabel(); - C->True = newlabel(); - C->False = next; S2->begin = newlabel(); S2->next = newlabel(); S3->next = begin; S1->code(fp); fprintf(fp, "L%d:\n", begin); C->code(fp); - fprintf(fp, "L%d:\n", C->True); + fprintf(fp, "L%d:\n", C->True); // False跳转 S3->code(fp); fprintf(fp, "L%d:\n", S2->begin); S2->code(fp); @@ -408,8 +365,8 @@ struct Function : Word{ for (iter = params->ids.begin(); iter != params->ids.end(); iter++){ (*iter)->offset = width; (*iter)->global = false; - fprintf(fp, "\t;%s @%d\n", (*iter)->s->word.c_str(), width); - width += (*iter)->t->width; + fprintf(fp, "\t;%s @%d\n", (*iter)->getName(), width); + width += (*iter)->getWidth(); } width = 0; Symbols *table = symbols; @@ -417,8 +374,8 @@ struct Function : Word{ for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ (*iter)->offset = width; (*iter)->global = false; - fprintf(fp, "\t;%s @%d\n", (*iter)->s->word.c_str(), width); - width += (*iter)->t->width; + fprintf(fp, "\t;%s @%d\n", (*iter)->getName(), width); + width += (*iter)->getWidth(); } } fprintf(fp, "\tsub $sp %d\n", width); @@ -427,7 +384,7 @@ struct Function : Word{ for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ (*iter)->offset = width; (*iter)->global = false; - width += (*iter)->t->width; + width += (*iter)->getWidth(); } } body->code(fp); @@ -438,7 +395,7 @@ struct Function : Word{ struct Call :Expr{ list args; Function *func; - Call() :Expr("@"){ args.clear(); } + Call() { args.clear(); } virtual void code(FILE *fp){ Stmt::code(fp); printf("call\n"); @@ -469,8 +426,8 @@ struct Global :Node{ for (iter = ids.begin(); iter != ids.end(); iter++){ (*iter)->offset = width; (*iter)->global = true; - fprintf(fp, "\t%s %s\n", (*iter)->t->word.c_str(), (*iter)->s->word.c_str()); - width += (*iter)->t->width; + fprintf(fp, "\t%s %s\n", (*iter)->getTypeName(), (*iter)->getName()); + width += (*iter)->getWidth(); } } fprintf(fp, ".stack\n"); diff --git a/Parser/lexer.h b/Parser/lexer.h index 2c1566e..a2f68b6 100644 --- a/Parser/lexer.h +++ b/Parser/lexer.h @@ -10,6 +10,7 @@ #include #include #include +#include using namespace std; @@ -64,6 +65,7 @@ struct Word :Token{ virtual string code(){ return word; } + const char* getName() { return word.c_str(); } }; struct Type :Word{ @@ -80,7 +82,7 @@ struct Type :Word{ } }; -Type* Type::Int = new Type(BASIC, "dw", 2); +Type* Type::Int = new Type(BASIC, "dw", 4); Type* Type::Char = new Type(BASIC, "db", 1); Type* Type::Void = new Type(BASIC, "void", 0); @@ -97,13 +99,61 @@ struct Integer :Token{ } }; +class ReadBuffer { +private: + FILE *file; + char *buf; + int front, rear; +public: + const int size = 3; + ReadBuffer() { + front = 0, rear = 0; + } + ~ReadBuffer() { + if (file) + fclose(file); + } + void open(char *filename) { + file = fopen(filename, "rb"); + } + char operator[](int i) { + return buf[(front + i) % size]; + } + char peak() { + return buf[front % size]; + } + void pop() { + if (!isempty()) { + front = (front + 1) % size; + read(); + } + } + bool isempty() { + return (front == rear); + } + bool isfull() { + return ((rear + 1) % size) == front; + } + void read() { + while (!isfull()) { + size_t sz = fread(buf+rear, sizeof(char), 1, file); + if (sz == 0) { + // 终止 + buf[rear-1] = '\0'; + break; + } + rear = (rear + sz) % size; + } + } +}; + // 词法分析器 class Lexer{ - ifstream inf; map words; + ReadBuffer buffer; public: int line = 1; - Lexer(string fp){ + Lexer(){ words["int"] = Type::Int; words["char"] = Type::Char; words["void"] = Type::Void; @@ -121,19 +171,37 @@ class Lexer{ words["catch"] = new Word(CATCH, "catch"); words["finally"] = new Word(FINALLY, "finally"); words["throw"] = new Word(THROW, "throw"); - inf.open(fp, ios::in); + // Operator + words["&"] = new Word(BIT_AND, "&"); // BIT LOGIC + words["|"] = new Word(BIT_OR, "|"); + words["~"] = new Word(BIT_NOT, "~"); + words["&&"] = new Word(AND, "AND"); // LOGIC + words["||"] = new Word(OR, "OR"); + words["<<"] = new Word(SHL, "SHL"); // SHIFT + words[">>"] = new Word(SHR, "SHR"); + words["=="] = new Word(EQ, "EQ"); // COMP + words["!="] = new Word(NEQ, "NEQ"); + words["<"] = new Word(LT, "LT"); + words["<="] = new Word(LEQ, "LEQ"); + words[">="] = new Word(GEQ, "GEQ"); + words[">"] = new Word(GT, "GT"); } ~Lexer(){ - inf.close(); - words.clear(); printf("~Lexer\n"); + words.clear(); } - Integer* match_integer(char ch) { + void open(char *filename) { + buffer.open(filename); + } + Integer* match_integer(ReadBuffer & buffer) { int value = 0; + char ch = buffer.peak(); + buffer.pop(); if (ch == '0') { - inf.read(&ch, sizeof(ch)); + ch = buffer.peak(); if (ch == 'x' || ch == 'X') { - inf.read(&ch, sizeof(ch)); + ch = buffer.peak(); + buffer.pop(); if (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')) { do { if (isalpha(ch)) { @@ -142,27 +210,29 @@ class Lexer{ else { value = 16 * value + ch - '0'; } - inf.read(&ch, sizeof(ch)); + ch = buffer.peak(); + buffer.pop(); } while (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')); - inf.seekg(-1, ios::cur); return new Integer(NUM, value); } else { printf("错误的十六进制!"); + return nullptr; } } else if (ch >= '0'&&ch <= '7') { //八进制整数 do { value = 8 * value + ch - '0'; - inf.read(&ch, sizeof(ch)); + ch = buffer.peak(); + buffer.pop(); } while (ch >= '0'&&ch <= '7'); - inf.seekg(-1, ios::cur); + buffer.read(); return new Integer(NUM, value); } else { //十进制整数0 - inf.seekg(-1, ios::cur); + buffer.read(); return new Integer(NUM, 0); } } @@ -170,43 +240,61 @@ class Lexer{ //除0外十进制整数,5状态 do { value = 10 * value + ch - '0'; - inf.read(&ch, sizeof(ch)); + ch = buffer.peak(); + buffer.pop(); } while (isdigit(ch)); - inf.seekg(-1, ios::cur);//回退一个字符 return new Integer(NUM, value); } } - void match_operator(char ch) { - + Token* match_operator(ReadBuffer & buffer) { + char ch[3]; + memset(ch, 0, sizeof(char) * 3); + ch[0] = buffer.peak(); + buffer.pop(); + ch[1] = buffer.peak(); + switch (ch[1]) { + case '&': + case '|': + case '<': + case '>': + case '=': + buffer.pop(); + return words[ch];// 运算符 + break; + default: + break; + } + ch[1] = '\0'; + if (words.find(ch) != words.end()) { + return words[ch];// 运算符 + } + return new Token(ch[0]);//普通字符 } Token *scan() { - int i = 0; char ch; do{ - inf.read(&ch, sizeof(ch)); + ch = buffer.peak(); if (ch == '\n')line++; + buffer.pop(); } while (ch == ' ' || ch == '\n' || ch == '\t'); - if (ch == EOF){ - return new Token(END); - } if (isalpha(ch)){ string str; do{ str.push_back(ch); - inf.read(&ch, sizeof(ch)); + ch = buffer.peak(); + buffer.read(); } while (isalnum(ch) || ch == '_'); //1状态 - inf.seekg(-1, ios::cur);//回退一个字符 if (words.find(str) == words.end()){ return new Word(ID, str); } return words[str]; } if (isdigit(ch)){ - return match_integer(ch); + return match_integer(buffer); } - return new Token(ch); + return match_operator(buffer); } }; diff --git a/Parser/main.cpp b/Parser/main.cpp index 779b345..a1a6aa1 100644 --- a/Parser/main.cpp +++ b/Parser/main.cpp @@ -4,9 +4,9 @@ void main(){ char a; FILE file; FILE *fp = &file; - Parser *p = new Parser("Text.txt"); + Parser *p = new Parser(); printf("开始语法分析\n"); - Node *st = p->parse(); + Node *st = p->parse("Text.txt"); printf("语法分析结束\n"); printf("编译开始\n"); printf(" line stmt\n"); diff --git a/Parser/parser.h b/Parser/parser.h index c449f28..e17c80f 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -38,22 +38,43 @@ class Parser{ return nullptr; } void init_precedence() { - precedence["*"] = 3; // term + precedence["[]"] = 1; // level 1 + precedence["()"] = 1; + precedence["->"] = 1; + precedence["."] = 1; + + precedence["!"] = 2; // level 2 + precedence["~"] = 2; + precedence["++"] = 2; + precedence["--"] = 2; + precedence["-"] = 2; + //precedence["(T)"] = 2; + //precedence["*"] = 2; + //precedence["&"] = 2; + precedence["sizeof"] = 2; + + precedence["*"] = 3; // level 3 precedence["/"] = 3; precedence["%"] = 3; - precedence["+"] = 4; // expr + + precedence["+"] = 4; // level 4 precedence["-"] = 4; - precedence["<<"] = 5; // shift + + precedence["<<"] = 5; // level 5 precedence[">>"] = 5; - precedence["<"] = 6; // rel + + precedence["<"] = 6; // level 6 precedence["<="] = 6; precedence[">="] = 6; precedence[">"] = 6; - precedence["=="] = 7; // rel + + precedence["=="] = 7; // level 7 precedence["!="] = 7; - precedence["&"] = 8; // bitop - precedence["^"] = 9; + + precedence["&"] = 8; // bit logic + precedence["~"] = 3; precedence["|"] = 10; + precedence["&&"] = 11; // logical precedence["||"] = 12; } @@ -311,50 +332,17 @@ class Parser{ BinaryExpr* expr_binary() { Expr* pL = expr_binary(); while (s->kind) { - if (compare(s->kind, pL->opt)) { + Word* w = (Word*)s; + if (compare(w->word, pL->opt)) { Expr* pR = expr_binary(); } - pL = new BinaryExpr(opt, pL, pR); + pL = new BinaryExpr(w->word, pL, pR); } return pL; } UnaryExpr* expr_unary() { match('-'); } - //Cond* expr_cond() - //{ - // Expr* e = expr_expr(); - // if (s->kind == '<' || s->kind == '>' || s->kind == '=' || s->kind == '!'){ - // char opt = s->kind; - // match(s->kind); - // Expr *r = expr_expr(); - // return new Cond(opt, e, r); - // } - // return nullptr; - //} - //Expr* expr_expr() - //{ - // Expr* e = expr_term(); - // while (s->kind == '+' || s->kind == '-'){ - // char opt = s->kind; - // match(s->kind); - // Expr *r = expr_term(); - // e = new Arith(opt, e, r); - // } - // return e; - //} - //Expr* expr_term() - //{ - // Expr* e = expr_unary(); - // while (s->kind == '*' || s->kind == '/' || s->kind == '%') - // { - // string opt(s->kind); - // match(s->kind); - // Expr *r = expr_unary(); - // e = new Arith(opt, e, r); - // } - // return e; - //} UnaryExpr* expr_unary(){ Expr *u; if (s->kind == '~'){ @@ -402,9 +390,9 @@ class Parser{ return c; } public: - Parser(string fp){ + Parser(){ init_precedence(); - lexer = new Lexer(fp); + lexer = new Lexer(); symbols = new Symbols(); globol = new Global(); } @@ -415,7 +403,8 @@ class Parser{ delete symbols; delete globol; } - Node* parse(){ + Node* parse(char *filename){ + lexer->open(filename); s = lexer->scan();// 预读一个词法单元,以便启动语法分析 node(); return globol; From bffa8b29be5c62a25e8cee2811fc23405264c6a3 Mon Sep 17 00:00:00 2001 From: mbs0221 Date: Fri, 27 Sep 2019 14:30:55 +0800 Subject: [PATCH 19/22] update assembler and parser --- Asm/asm.h | 388 ++++++++++++++++++++++++------------------------ Asm/inter.h | 181 ++++++++++++---------- Asm/lexer.h | 35 +++-- Asm/vm.h | 17 ++- Parser/inter.h | 245 ++++++++++++++++++------------ Parser/lexer.h | 2 +- Parser/main.cpp | 4 +- Parser/parser.h | 42 +++--- 8 files changed, 491 insertions(+), 423 deletions(-) diff --git a/Asm/asm.h b/Asm/asm.h index 7477230..08cbf76 100644 --- a/Asm/asm.h +++ b/Asm/asm.h @@ -11,6 +11,55 @@ using namespace std; +//-------------------------异常处理------------------------ +class MismatchException : public exception { + int line; +public: + MismatchException(int line) : exception(), line(line) { ; } + const char * what() const throw () { + return "Character mismatch"; + } +}; + +class UndeclaredException : public exception { + int line; +public: + UndeclaredException(int line) : exception(), line(line) { ; } + const char * what() const throw () { + return "Variable or function undeclared"; + } +}; + +class MultipleDeclaredException : exception { + int line; +public: + MultipleDeclaredException(int line) : exception(), line(line) { ; } + const char * what() const throw () { + return "Multiple labels are declared"; + } +}; + +class InstructionUnsupportedException : exception { + int line; +public: + InstructionUnsupportedException(int line) : exception(), line(line) { ; } + const char * what() const throw () { + return "Instruction unsupported"; + } +}; + +#define MATCH_REG(l, s) \ + match('$'); \ + l->reg = ((Integer*)s)->value; \ + match(NUM); + +#define MATCH_ADDR(l, s) \ + match('#'); \ + l->addr = ((Integer*)s)->value; \ + match(NUM); + +//-------------------------汇编程序------------------------ + class Asm{ private: int DS = 0; @@ -20,253 +69,182 @@ class Asm{ Lexer *lexer; Codes *cs; map lables; - map funcs; - bool match(int kind){ - if (s->kind == kind){ - s = lexer->scan(); - return true; + map funcs; + // basic opts + inline BYTE match_reg() { + match('$'); + BYTE reg = ((Integer*)s)->value; + match(NUM); + return reg; + } + inline WORD match_addr() { + match('#'); + WORD addr = ((Integer*)s)->value; + match(NUM); + return addr; + } + inline Word* match_word() { + Word *w = (Word*)s; + match(ID); + return w; + } + // labels + Code* add_label(string name) { + if (lables.find(name) == lables.end()) { + lables[name] = new Label(lexer->line, name); + } + return lables[name]; + } + // parser + void match(int kind){ + if (s->kind != kind){ + throw MismatchException(lexer->line); } s = lexer->scan(); - return false; } void data(){ - printf("[%03d]data.\n", lexer->line); match('.'); match(DATA); - cs->offset = cs->width; - cs->width += ((Integer*)s)->value; - DS = 0; + //cs->offset = cs->width; + //cs->width += ((Integer*)s)->value; + //DS = 0; match(NUM); } void stack(){ - printf("[%03d]stack.\n", lexer->line); match('.'); match(STACK); - cs->offset = cs->width; - cs->width += ((Integer*)s)->value; - SS = cs->width; + //cs->offset = cs->width; + //cs->width += ((Integer*)s)->value; + //SS = cs->width; match(NUM); } void code(){ match('.'); match(CODE); - CS = cs->offset; s = lexer->scan(); - Code *c = new Code; + Code *c = new Code(0, CODE); while (s->kind == PROC){ - c = proc(); + c = match_proc(); if (c){ - printf("[%03d]find proc.\n", c->line); - cs->codes.push_back(c); - c->offset = cs->width; - cs->width += c->width; + cs->pushCode(c); } } match('#'); } - Code* proc(){ - Func *f = new Func; - printf("[%03d]proc.\n", lexer->line); + Code* match_proc(){ match(PROC); - f->line = lexer->line; - f->offset = cs->width; - f->name = ((Word*)s)->word; - f->width = 0; - match(ID); + Word *w = match_word(); match(':'); - funcs[f->name] = f; - Code *c = new Code; - while (s->kind != ENDP){ - switch (s->kind){ - case ID:c = label(); break; - case CALL: c = call(); break; - case LOAD:c = load(); break; - case STORE:c = store(); break; - case PUSH:c = push(); break; - case POP:c = pop(); break; - case HALT:c = halt(); break; - case JE: c = jmp(JE); break; - case JNE: c = jmp(JNE); break; - case JB: c = jmp(JB); break; - case JG: c = jmp(JG); break; - case JMP: c = jmp(JMP); break; - case '~':c = unary(); break; - case ADD:c = arith(ADD); break; - case SUB:c = arith(SUB); break; - case '+':c = arith(ADD); break; - case '-':c = arith(SUB); break; - case '*':c = arith(MUL); break; - case '/':c = arith(DIV); break; - case '%':c = arith(MOD); break; - case '<':c = arith(CMP); break; - case '>':c = arith(CMP); break; - case '=':c = arith(CMP); break; - case '!':c = arith(CMP); break; - default:printf("[%3d]find unsupported cmd '%c\n", lexer->line, s->kind); break; + Code *body = match_codes(); + match(ENDP); + Proc *proc = new Proc(lexer->line, w->word, body); + funcs[w->word] = proc; + return proc; + } + Code* match_codes() { + Codes *cs, *c; + cs = new Codes(lexer->line); + while (s->kind != ENDP) { + Code *c; + switch (s->kind) { + case ID:c = match_label(); break; + case CALL: c = match_call(); break; + case LOAD:c = match_load(); break; + case STORE:c = match_store(); break; + case PUSH:c = match_push(); break; + case POP:c = match_pop(); break; + case HALT:c = match_halt(); break; + case JE: + case JNE: + case JB: + case JG: + case JMP: c = match_jmp(); break; + case ADD: + case SUB: + case '+': + case '-': + case '*': + case '/': + case '%': + case '<': + case '>': + case '=':c = match_arith(); break; + case '!': + case '~':c = match_unary(); break; + default: throw InstructionUnsupportedException(lexer->line); break; } - if (c){ f->codes.push_back(c); c->offset = f->width; f->width += c->width; } + if (c) { cs->pushCode(c); } } - match(ENDP); - return f; } - Code* call(){ - Call *c = new Call; - c->line = lexer->line; - printf("[%03d]call.\n", lexer->line); + Code* match_label() { + Word *w = match_word(); + match(':'); + return add_label(w->word); + } + Code* match_call(){ match(CALL); - if (funcs.find(((Word*)s)->word) == funcs.end()){ - printf("[%3d] '%d' undeclared function.\n", lexer->line, s->kind); + Word *w = match_word(); + if (funcs.find(w->word) != funcs.end()){ + Proc *func = funcs[w->word]; match(ID); - return c; + return new Call(lexer->line, func); } - c->func = funcs[((Word*)s)->word]; - match(ID); - c->width = 3; - return c; + throw exception("", 1); + return nullptr; } - Code* pop(){ - Pop *p = new Pop; - printf("[%03d]pop.\n", lexer->line); - p->line = lexer->line; - p->opt = POP; - match(POP); - match('$'); - p->reg = ((Integer*)s)->value; - match(NUM); - p->width = 2; - return p; + Code* match_load() { + BYTE reg = match_reg(); + WORD addr = match_addr(); + return new Load(lexer->line, reg, addr); } - Code* push(){ - Push *p = new Push; - printf("[%03d]push.\n", lexer->line); - p->line = lexer->line; - p->opt = PUSH; - match(PUSH); - match('$'); - p->reg = ((Integer*)s)->value; - match(NUM); - p->width = 2; - return p; - } - Code* store(){ - Store *l = new Store; - Token *i = new Integer(NUM, 0);; - printf("[%03d]store.\n", lexer->line); - l->line = lexer->line; - l->opt = STORE; + Code* match_store(){ match(STORE); - match('$'); - l->reg = ((Integer*)s)->value; - match(NUM); - switch (s->kind){ - case NUM:l->am |= MR_A; i = s; match(NUM); break;// imm立即数寻址 - case '#':l->am |= MR_B; match('#'); i = s; match(NUM); break;// #addr直接寻址 - case '[':l->am |= MR_C; match('['); i = s; match(NUM); match(']'); break;// [addr]间接寻址 - case REG:l->am |= MR_D; i = s; match(REG); break;// reg寄存器寻址 - default:break; - } - l->addr = ((Integer*)i)->value; - l->width = 4; - return l; + BYTE reg = match_reg(); + WORD addr = match_addr(); + return new Store(lexer->line, reg, addr); } - Code* load(){ - Load *l = new Load; - Token *i = new Integer(NUM, 0); - printf("[%03d]load.\n", lexer->line); - l->line = lexer->line; - l->opt = LOAD; - match(LOAD); - match('$'); - l->reg = ((Integer*)s)->value; - match(NUM); - switch (s->kind){ - case NUM:l->am |= MR_A; i = s; match(NUM); break;// imm立即数寻址 - case '#':l->am |= MR_B; match('#'); i = s; match(NUM); break;// #addr直接寻址 - case '[':l->am |= MR_C; match('['); i = s; match(NUM); match(']'); break;// [addr]间接寻址 - case REG:l->am |= MR_D; i = s; match(REG); break;// reg寄存器寻址 - default:break; - } - l->addr = ((Integer*)i)->value; - l->width = 4; - return l; + Code* match_push() { + match(PUSH); + BYTE reg = match_reg(); + return new Push(lexer->line, reg); } - Code* label(){ - printf("[%03d]label.\n", lexer->line); - if (lables.find(((Word*)s)->word) == lables.end()){ - lables[((Word*)s)->word] = new Label((Word*)s, cs->width); - }else{ - lables[((Word*)s)->word]->offset = cs->width; - } - match(ID); - match(':'); - return nullptr; + Code* match_pop() { + match(POP); + BYTE reg = match_reg(); + match(NUM); + return new Pop(lexer->line, reg); } - Code* unary(){ - Unary *u = new Unary; - printf("[%03d]unary.\n", lexer->line); - u->line = lexer->line; + Code* match_unary(){ match('~'); - u->opt = NEG; - match('$'); - u->reg1 = ((Integer*)s)->value; - match(NUM); - match('$'); - u->reg2 = ((Integer*)s)->value; - match(NUM); - u->width = 3; - return u; + BYTE reg1 = match_reg(); + BYTE reg2 = match_reg(); + return new Unary(lexer->line, NEG, reg1, reg2); } - Code* arith(BYTE b){ - Arith *a = new Arith; - printf("[%03d]arith.\n", lexer->line); - a->line = lexer->line; - a->opt = b; + Code* match_arith(){ + BYTE opt = s->kind; match(s->kind); - match('$'); - a->reg1 = ((Integer*)s)->value; - match(NUM); - match('$'); - a->reg2 = ((Integer*)s)->value; - match(NUM); - match('$'); - a->reg3 = ((Integer*)s)->value; - match(NUM); - a->width = 4; - return a; + BYTE reg1 = match_reg(); + BYTE reg2 = match_reg(); + BYTE reg3 = match_reg(); + return new Arith(lexer->line, opt, reg1, reg2, reg3); } - Code* jmp(BYTE b){ - Jmp *j = new Jmp; - printf("[%03d]jmp.\n", lexer->line); - j->line = lexer->line; - j->opt = b; - match(s->kind); - if (lables.find(((Word*)s)->word) == lables.end()){ - // 没有标签 - j->addr = new Label((Word*)s, cs->width); - lables[((Word*)s)->word] = j->addr; - } - else{ - j->addr = lables[((Word*)s)->word]; - } + Code* match_jmp(){ + match(JMP); + Word *w = match_word(); + Label *label = (Label*)add_label(w->word); match(ID); - j->width = 3; - return j; + return new Jmp(lexer->line, label); } - Code* halt(){ - Halt *h = new Halt; - printf("[%03d]halt.\n", lexer->line); - h->line = lexer->line; - h->opt = HALT; - h->width = 1; + Code* match_halt(){ match(HALT); - return h; + return new Halt(lexer->line); } public: Asm(string fp){ lexer = new Lexer(fp); } void parse(){ - cs = new Codes; + cs = new Codes(lexer->line); data(); stack(); code(); @@ -276,10 +254,24 @@ class Asm{ fwrite(&DS, sizeof(WORD), 1, fp); fwrite(&CS, sizeof(WORD), 1, fp); fwrite(&SS, sizeof(WORD), 1, fp); - fwrite(&cs->width, sizeof(WORD), 1, fp); + //fwrite(&cs->width, sizeof(WORD), 1, fp); //fwrite(&b, sizeof(BYTE)*CS, 1, fp); cs->code(fp); } }; + +//printf("[%03d]data.\n", lexer->line); +//printf("[%03d]stack.\n", lexer->line); +//printf("[%03d]proc.\n", lexer->line); +//printf("[%03d]call.\n", lexer->line); +//printf("[%03d]pop.\n", lexer->line); +//printf("[%03d]push.\n", lexer->line); +//printf("[%03d]load.\n", lexer->line); +//printf("[%03d]store.\n", lexer->line); +//printf("[%03d]label.\n", lexer->line); +//printf("[%03d]unary.\n", lexer->line); +//printf("[%03d]arith.\n", lexer->line); +//printf("[%03d]jmp.\n", lexer->line); +//printf("[%03d]halt.\n", lexer->line); #endif \ No newline at end of file diff --git a/Asm/inter.h b/Asm/inter.h index 72b9adf..27a4b7e 100644 --- a/Asm/inter.h +++ b/Asm/inter.h @@ -1,27 +1,33 @@ #include "lexer.h" -// 标签 -struct Label{ - Word *w; - WORD offset; - Label(Word *w, int offset) :w(w), offset(offset) { } -}; //----------------参考RISC指令集---------------- -// 代码 -struct Code{ +class Code { +protected: BYTE opt; WORD line = 0;// 当前指令在汇编文件中的位置 - WORD width = 0;// 当前代码所占用的宽度 WORD offset = 0;// 当前代码段的偏移量 +public: + int getWitdh() { return 0; } + Code(int line, BYTE opt) :line(line), opt(opt) { ; } virtual void code(FILE* fp){ - printf("[%04d][%04d][%04x]", line, width, offset); + printf("[%04d][%04x]", line, offset); } }; -// 代码块 -struct Codes :Code{ +class Codes : public Code{ list codes; +public: + Codes(int line) : Code(line, CODE) { ; } + void pushCode(Code *c) { codes.push_back(c); } + int getWidth() { + int width; + list::iterator iter; + for (iter = codes.begin(); iter != codes.end(); iter++) { + width += (*iter)->getWitdh(); + } + return width; + } virtual void code(FILE* fp){ list::iterator iter; for (iter = codes.begin(); iter != codes.end(); iter++){ @@ -30,54 +36,67 @@ struct Codes :Code{ } }; -// 数据段 -struct Data :Code{ +class Data : public Code{ + int width; +public: virtual void code(FILE* fp){ Code::code(fp); - printf("data:%2d\n", width); - for (WORD i = 0; i < width; i++){ - fwrite(&opt, sizeof(BYTE), 1, fp); - } + printf("data:\n"); + //for (WORD i = 0; i < width; i++){ + // fwrite(&opt, sizeof(BYTE), 1, fp); + //} } }; -// 函数 -struct Func :Code{ +class Label : public Code { string name; - list codes; - virtual void code(FILE* fp){ - list::iterator iter; - for (iter = codes.begin(); iter != codes.end(); iter++){ - (*iter)->code(fp); - } +public: + Label(int line, string name) : Code(line, LABEL), name(name) { ; } +}; + +class Proc : public Code { + string name; + Code *body; +public: + Proc(int line, string name, Code *body) :Code(line, PROC), name(name), body(body) { ; } + virtual void code(FILE* fp) { + Code::code(fp); + body->code(fp); } }; -// 参数传递 -struct Param :Code{ - BYTE reg;// 寄存器 - virtual void code(FILE* fp){ +class Arith : public Code { + BYTE reg1, reg2, reg3; +public: + Arith(int line, BYTE opt, BYTE reg1, WORD reg2, WORD reg3) : Code(line, opt), reg1(reg1), reg2(reg2), reg3(reg3) { ; } + virtual void code(FILE* fp) { Code::code(fp); - printf("param\t$%04x;%s\n", opt, reg); + printf("bino\t$%02x $%02x $%02x $%02x\n", opt, reg1, reg2, reg3); fwrite(&opt, sizeof(BYTE), 1, fp); + fwrite(®1, sizeof(BYTE), 1, fp); + fwrite(®2, sizeof(BYTE), 1, fp); + fwrite(®3, sizeof(BYTE), 1, fp); } }; -// 函数调用 -struct Call :Code{ - Func *func;// 函数 - virtual void code(FILE* fp){ +class Unary : public Code { + BYTE reg1, reg2; +public: + Unary(int line, BYTE opt, BYTE reg1, BYTE reg2) :Code(line, opt), reg1(reg1), reg2(reg2) { ; } + virtual void code(FILE* fp) { Code::code(fp); - printf("call\t$%04x;%s\n", func->offset, func->name.c_str()); + printf("unary\t$%02x $%02x $%02x\n", opt, reg1, reg2); fwrite(&opt, sizeof(BYTE), 1, fp); + fwrite(®1, sizeof(BYTE), 1, fp); + fwrite(®2, sizeof(BYTE), 1, fp); } }; -// Load指令 -struct Load :Code{ - BYTE am;// 内存地址寻址方式 - BYTE reg;// 通用寄存器 - WORD addr;// RAM地址 +class Load : public Code{ + BYTE reg; + WORD addr; +public: + Load(int line, BYTE reg, WORD addr) : Code(line, LOAD), reg(reg), addr(addr) { } virtual void code(FILE* fp){ Code::code(fp); printf("load\t$%02x $%02x $%04x\n", opt, reg, addr); @@ -85,25 +104,26 @@ struct Load :Code{ fwrite(®, sizeof(BYTE), 1, fp); fwrite(&addr, sizeof(WORD), 1, fp); } -};// 直接寻址 +}; -// Store指令 -struct Store :Code{ - BYTE am;// 内存地址寻址方式 - BYTE reg;// 通用寄存器 - WORD addr;// RAM地址 +class Store : public Code { + BYTE reg; + WORD addr; +public: + Store(int line, BYTE reg, WORD addr) : Code(line, STORE), reg(reg), addr(addr) { } virtual void code(FILE* fp){ Code::code(fp); - printf("store\t$%02x $%02x $%04x\n", opt, reg, addr); + printf("store\t$%02x $%02x $%04x\n", STORE, reg, addr); fwrite(&opt, sizeof(BYTE), 1, fp); fwrite(®, sizeof(BYTE), 1, fp); fwrite(&addr, sizeof(WORD), 1, fp); } }; -// 入栈指令 -struct Push :Code{ +class Push : public Code{ BYTE reg; +public: + Push(int line, BYTE reg) : Code(line, PUSH), reg(reg) { ; } virtual void code(FILE* fp){ Code::code(fp); printf("push\t$%02x $%02x\n", opt, reg); @@ -112,9 +132,10 @@ struct Push :Code{ } }; -// 出栈指令 -struct Pop :Code{ +class Pop : public Code{ BYTE reg; +public: + Pop(int line, BYTE reg) : Code(line, POP), reg(reg) { ; } virtual void code(FILE* fp){ Code::code(fp); printf("pop\t$%02x $%02x\n", opt, reg); @@ -123,48 +144,44 @@ struct Pop :Code{ } }; -// 停机指令 -struct Halt:Code{ - virtual void code(FILE* fp){ +class Jmp : public Code { + Label *label; +public: + Jmp(int line, Label *label) : Code(line, JMP), label(label) { ; } + virtual void code(FILE* fp) { Code::code(fp); - opt = HALT; - printf("halt\t$%02x\n", opt); - fwrite(&opt, sizeof(BYTE), 1, fp); + //printf("jmp \t$%02x $%04x\n", opt, addr->offset); + //fwrite(&opt, sizeof(BYTE), 1, fp); + //fwrite(&addr->offset, sizeof(WORD), 1, fp); } }; -// 跳转指令 -struct Jmp :Code{ - Label *addr; - virtual void code(FILE* fp){ +class Param : public Code { + BYTE reg;// 寄存器 + virtual void code(FILE* fp) { Code::code(fp); - printf("jmp \t$%02x $%04x\n", opt, addr->offset); - fwrite(&opt, sizeof(BYTE), 1, fp); - fwrite(&addr->offset, sizeof(WORD), 1, fp); + //printf("param\t$%04x;%s\n", opt, reg); + //fwrite(&opt, sizeof(BYTE), 1, fp); } }; -// 双目运算指令 -struct Arith :Code{ - BYTE reg1, reg2, reg3; - virtual void code(FILE* fp){ +class Call : public Code { + Proc *func;// 函数 +public: + Call(int line, Proc *func) : Code(line, PROC), func(func) { ; } + virtual void code(FILE* fp) { Code::code(fp); - printf("bino\t$%02x $%02x $%02x $%02x\n", opt, reg1, reg2, reg3); - fwrite(&opt, sizeof(BYTE), 1, fp); - fwrite(®1, sizeof(BYTE), 1, fp); - fwrite(®2, sizeof(BYTE), 1, fp); - fwrite(®3, sizeof(BYTE), 1, fp); + //printf("call\t$%04x;%s\n", func->offset, func->name.c_str()); + //fwrite(&opt, sizeof(BYTE), 1, fp); } }; -// 单目运算指令 -struct Unary :Code{ - BYTE reg1, reg2; +class Halt: public Code { +public: + Halt(int line) : Code(line, HALT) { ; } virtual void code(FILE* fp){ Code::code(fp); - printf("unary\t$%02x $%02x $%02x\n", opt, reg1, reg2); - fwrite(&opt, sizeof(BYTE), 1, fp); - fwrite(®1, sizeof(BYTE), 1, fp); - fwrite(®2, sizeof(BYTE), 1, fp); + //printf("halt\t$%02x\n", opt); + //fwrite(&opt, sizeof(BYTE), 1, fp); } -}; +}; \ No newline at end of file diff --git a/Asm/lexer.h b/Asm/lexer.h index d19d36e..3b06179 100644 --- a/Asm/lexer.h +++ b/Asm/lexer.h @@ -73,6 +73,9 @@ struct Integer :Token{ } }; +#define DEF_KEY_WORD(key, type, value) words[key] = new Integer(type, value) + + // 词法分析器 class Lexer{ ifstream inf; @@ -133,22 +136,22 @@ class Lexer{ // MIPS指令集 void MIPS(){ // R-type - words["add"] = new Integer(RTYPE, 0x00000020); - words["addu"] = new Integer(RTYPE, 0x00000021); - words["sub"] = new Integer(RTYPE, 0x00000022); - words["subu"] = new Integer(RTYPE, 0x00000023); - words["and"] = new Integer(RTYPE, 0x00000024); - words["or"] = new Integer(RTYPE, 0x00000025); - words["xor"] = new Integer(RTYPE, 0x00000026); - words["nor"] = new Integer(RTYPE, 0x00000027); - words["slt"] = new Integer(RTYPE, 0x0000002A); - words["sltu"] = new Integer(RTYPE, 0x0000002B); - words["sll"] = new Integer(RTYPE, 0x00000000); - words["srl"] = new Integer(RTYPE, 0x00000002); - words["ara"] = new Integer(RTYPE, 0x00000003); - words["add"] = new Integer(RTYPE, 0x00000004); - words["add"] = new Integer(RTYPE, 0x00000005); - words["srav"] = new Integer(RTYPE, 0x00000006); + DEF_KEY_WORD("add",RTYPE, 0x00000020); + DEF_KEY_WORD("addu",RTYPE, 0x00000021); + DEF_KEY_WORD("sub",RTYPE, 0x00000022); + DEF_KEY_WORD("subu",RTYPE, 0x00000023); + DEF_KEY_WORD("and",RTYPE, 0x00000024); + DEF_KEY_WORD("or",RTYPE, 0x00000025); + DEF_KEY_WORD("xor",RTYPE, 0x00000026); + DEF_KEY_WORD("nor",RTYPE, 0x00000027); + DEF_KEY_WORD("slt",RTYPE, 0x0000002A); + DEF_KEY_WORD("sltu",RTYPE, 0x0000002B); + DEF_KEY_WORD("sll",RTYPE, 0x00000000); + DEF_KEY_WORD("srl",RTYPE, 0x00000002); + DEF_KEY_WORD("ara",RTYPE, 0x00000003); + DEF_KEY_WORD("add",RTYPE, 0x00000004); + DEF_KEY_WORD("add",RTYPE, 0x00000005); + DEF_KEY_WORD("srav",RTYPE, 0x00000006); // I-Type // J-Type diff --git a/Asm/vm.h b/Asm/vm.h index 0eba496..36cf4b4 100644 --- a/Asm/vm.h +++ b/Asm/vm.h @@ -17,14 +17,15 @@ using namespace std; #define BIT_ERR 0x0001 // 内存寻址方式 -#define MR_A 0x80// imm立即寻址 -#define MR_B 0x40// addr直接寻址 -#define MR_C 0x20// [addr]间接寻址 -#define MR_D 0x10// reg寄存器寻址 -#define MR_E 0x08// [reg]寄存器间接寻址 -#define MR_F 0x04// offset相对寻址 -#define MR_G 0x02// [BP]基址寻址 -#define MR_H 0x01// [reg+addr]变址寻址 +//#define MR_A 0x80// imm立即寻址 +//#define MR_B 0x40// addr直接寻址 +//#define MR_C 0x20// [addr]间接寻址 +//#define MR_D 0x10// reg寄存器寻址 +//#define MR_E 0x08// [reg]寄存器间接寻址 +//#define MR_F 0x04// offset相对寻址 +//#define MR_G 0x02// [BP]基址寻址 +//#define MR_H 0x01// [reg+addr]变址寻址 + // 字/字节操作 #define MR_BYTE 0x80 // [111][111][0][0] diff --git a/Parser/inter.h b/Parser/inter.h index b167bb2..de87fd7 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -6,16 +6,21 @@ #include #include -struct Node{ +class Visitor; + +class ASTNode{ + friend class Visitor; +public: virtual void code(FILE *fp){ } }; -struct Nodes :Node{ - list nodes; +class Nodes :ASTNode{ + list nodes; +public: virtual void code(FILE *fp){ - list::iterator iter; + list::iterator iter; for (iter = nodes.begin(); iter != nodes.end(); iter++){ (*iter)->code(fp); } @@ -23,15 +28,16 @@ struct Nodes :Node{ }; //语句 -struct Stmt :Node{ +class Stmt :ASTNode{ int line; int begin, next; static int label; +public: static int newlabel(){ return label++; } virtual void code(FILE *fp){ - Node::code(fp); + ASTNode::code(fp); printf("[%04d]", line); } }; @@ -39,8 +45,9 @@ struct Stmt :Node{ int Stmt::label = 0; //语句块 -struct Stmts :Stmt{ +class Stmts :Stmt{ list Ss; +public: virtual void code(FILE *fp){ Stmt::code(fp); printf("stmts\n"); @@ -52,44 +59,42 @@ struct Stmts :Stmt{ }; //表达式 -struct Expr :Stmt{ +class ExprAST : Stmt{ int label; static int count; - Expr() { label = count++; } +public: + ExprAST() { label = count++; } virtual void code(FILE *fp){ - Node::code(fp); + ASTNode::code(fp); } }; -int Expr::count = 0; +int ExprAST::count = 0; // 双目表达式 -struct BinaryExpr : Expr { +class BinaryExpr : ExprAST { Word opt; - Expr *pL, *pR; - BinaryExpr(Word &opt, Expr *pL, Expr *pR) : opt(opt), pL(pL), pR(pR) { ; } + ExprAST *pL, *pR; +public: + BinaryExpr(Word &opt, ExprAST *pL, ExprAST *pR) : opt(opt), pL(pL), pR(pR) { ; } virtual void code(FILE *fp) override { - Expr::code(fp); - pL->code(fp); - pR->code(fp); - fprintf(fp, "\t%c $%d $%d $%d\n", opt.word.c_str(), pL->label, pR->label, label); + ExprAST::code(fp); } }; // 单目表达式 -struct UnaryExpr :Expr{ +class UnaryExpr :ExprAST{ Word opt; - Expr *E1; - UnaryExpr(Word &opt, Expr *E1) :opt(opt), E1(E1){ } + ExprAST *E1; +public: + UnaryExpr(Word &opt, ExprAST *E1) :opt(opt), E1(E1){ } virtual void code(FILE *fp){ - Expr::code(fp); - E1->code(fp); - fprintf(fp, "\t%c $%d $%d\n", opt, E1->label, label); + ExprAST::code(fp); } }; // ID -struct Id :Expr{ +class Id :ExprAST{ Type *type; Word *name; int offset; @@ -100,7 +105,7 @@ struct Id :Expr{ const char* getTypeName() { return type->word.c_str(); } int getWidth() { return type->width; } virtual void code(FILE *fp){ - Expr::code(fp); + ExprAST::code(fp); char *width = type == Type::Int ? "dw" : "b"; if (global){ fprintf(fp, "\tload%s $%d %s\n", width, label, name->getName()); @@ -110,18 +115,20 @@ struct Id :Expr{ } }; -struct Constant : Expr{ +class Constant : ExprAST{ Integer *s; +public: Constant(Integer *s) : s(s){ } virtual void code(FILE *fp){ - Expr::code(fp); + ExprAST::code(fp); char width = s->value > 256 ? 'w' : 'b'; fprintf(fp, "\tload%c $%d %d\n", width, label, s->value); } }; -struct Decl :Stmt{ +class Decl :Stmt{ list ids; +public: virtual void code(FILE *fp){ Stmt::code(fp); printf("data\n"); @@ -136,120 +143,127 @@ struct Decl :Stmt{ } }; -struct Assign :Stmt{ - Id *E1; - Expr *E2; +class Assign :Stmt{ + Id *id; + ExprAST *expr; +public: virtual void code(FILE *fp){ Stmt::code(fp); printf("assign\n"); - E2->code(fp); - if (E1->global){ - fprintf(fp, "\tstore %s $%d\n", E1->getName(), E2->label); + expr->code(fp); + if (id->global){ + fprintf(fp, "\tstore %s $%d\n", id->getName(), expr->label); }else{ - fprintf(fp, "\tstore %s $%d\n", E1->getName(), E2->label); + fprintf(fp, "\tstore %s $%d\n", id->getName(), expr->label); } } }; -struct If :Stmt{ - Expr *C; - Stmt *S1; +class If :Stmt{ + ExprAST *cond; + Stmt *body; +public: virtual void code(FILE *fp){ Stmt::code(fp); printf("if\n"); next = newlabel(); - S1->next = next; + body->next = next; // 计算表达式 - C->code(fp); + cond->code(fp); // 为False跳转 fprintf(fp, "jz L%d", next);// False跳转 - S1->code(fp); + body->code(fp); fprintf(fp, "L%d:\n", next); } }; -struct IfElse :Stmt{ - Expr *C; - Stmt *S1; - Stmt *S2; +class IfElse :Stmt{ + ExprAST *cond; + Stmt *body_t; + Stmt *body_f; +public: virtual void code(FILE *fp){ Stmt::code(fp); printf("if-else\n"); - S1->next = newlabel(); - S2->next = newlabel(); + body_t->next = newlabel(); + body_f->next = newlabel(); // 计算表达式 - C->code(fp); + cond->code(fp); // 为False跳转 fprintf(fp, "jz L%d:\n", next);// False跳转 - S1->code(fp); + body_t->code(fp); fprintf(fp, "\tjmp L%d\n", next); fprintf(fp, "L%d:\n", next); - S2->code(fp); - fprintf(fp, "L%d:\n", S1->next); + body_f->code(fp); + fprintf(fp, "L%d:\n", body_t->next); } }; -struct While :Stmt{ - Expr *C; - Stmt *S1; +class While :Stmt{ + ExprAST *cond; + Stmt *body; +public: virtual void code(FILE *fp){ Stmt::code(fp); printf("while\n"); begin = newlabel(); next = newlabel(); - S1->next = begin; + body->next = begin; fprintf(fp, "L%d:\n", begin); - C->code(fp); + cond->code(fp); fprintf(fp, "jz L:\n", next);// False跳转 - S1->code(fp); + body->code(fp); fprintf(fp, "\tjmp L%d\n", begin); fprintf(fp, "L%d:\n", next); } }; -struct Do :Stmt{ - Expr *C; - Stmt *S1; +class Do :Stmt{ + ExprAST *cond; + Stmt *body; +public: virtual void code(FILE *fp){ Stmt::code(fp); printf("do-while\n"); begin = newlabel(); - S1->next = begin; + body->next = begin; fprintf(fp, "L%d:\n", begin); - S1->code(fp); - C->code(fp); + body->code(fp); + cond->code(fp); fprintf(fp, "jnz L%d:\n", begin);// True跳转 } }; -struct For :Stmt{ - Stmt *S1; - Expr *C; - Stmt *S2; - Stmt *S3; +class For : Stmt{ + Stmt *init; + ExprAST *cond; + Stmt *step; + Stmt *body; +public: virtual void code(FILE *fp){ Stmt::code(fp); printf("for\n"); begin = newlabel(); next = newlabel(); - S2->begin = newlabel(); - S2->next = newlabel(); - S3->next = begin; - S1->code(fp); + step->begin = newlabel(); + step->next = newlabel(); + body->next = begin; + init->code(fp); fprintf(fp, "L%d:\n", begin); - C->code(fp); - fprintf(fp, "L%d:\n", C->True); // False跳转 - S3->code(fp); - fprintf(fp, "L%d:\n", S2->begin); - S2->code(fp); + cond->code(fp); + fprintf(fp, "L%d:\n", cond->label); // False跳转 + body->code(fp); + fprintf(fp, "L%d:\n", step->begin); + step->code(fp); fprintf(fp, "\tjmp L%d\n", begin); fprintf(fp, "L%d:\n", next); } }; -struct Case :Stmt{ - Expr *E; +class Case :Stmt{ + ExprAST *expr; map Ss; +public: virtual void code(FILE *fp){ Stmt::code(fp); printf("case\n"); @@ -260,18 +274,19 @@ struct Case :Stmt{ iter->second->code(fp); } fprintf(fp, "L%d:\n", begin); - E->code(fp); + expr->code(fp); for (iter = Ss.begin(); iter != Ss.end(); iter++){ fprintf(fp, "L%d:\n", iter->second->begin); - fprintf(fp, "= $%d $%d #%d\n", E->label, iter->first); + fprintf(fp, "= $%d $%d #%d\n", expr->label, iter->first); iter->second->code(fp); } } }; -struct Break :Stmt{ +class Break :Stmt{ Stmt *stmt; static stack cur; +public: Break(){ stmt = Break::cur.top(); } @@ -284,9 +299,10 @@ struct Break :Stmt{ stack Break::cur = stack(); -struct Continue :Stmt{ +class Continue :Stmt{ Stmt *stmt; static stack cur; +public: Continue(){ stmt = Continue::cur.top(); } @@ -300,8 +316,9 @@ struct Continue :Stmt{ stack Continue::cur = stack(); // 异常处理程序 -struct Throw : Stmt { +class Throw : Stmt { Type* exception;// 抛出异常 +public: Throw() { exception = nullptr; } @@ -312,8 +329,9 @@ struct Throw : Stmt { } }; -struct TryCatch : Stmt{ +class TryCatch : Stmt{ Stmt *pTry, *pCatch, *pFinally; +public: TryCatch() { pTry = pCatch = pFinally = nullptr; } @@ -332,12 +350,14 @@ struct TryCatch : Stmt{ } }; -// 符号表 -struct Symbols{ +// -------------符号表----------- + +class Symbols{ int id; static int count; list ids; Symbols *prev, *next; +public: Symbols(){ id = count++; ids.clear(); @@ -348,11 +368,14 @@ struct Symbols{ int Symbols::count = 0; -struct Function : Word{ +// -------------函数----------- + +class Function : Word{ Type *type; Symbols *params; Symbols *symbols; Stmt* body; +public: Function(string name, Type *type) :Word(FUNCTION, name), type(type){ kind = FUNCTION; params = new Symbols; @@ -392,15 +415,17 @@ struct Function : Word{ } }; -struct Call :Expr{ - list args; +class Call :ExprAST{ + list args; Function *func; +public: Call() { args.clear(); } + Call(int line, Function *func) :ExprAST(), func(func) { ; } virtual void code(FILE *fp){ Stmt::code(fp); printf("call\n"); // 参数计算 - list::iterator iter; + list::iterator iter; for (iter = args.begin(); iter != args.end(); iter++){ (*iter)->code(fp); } @@ -414,11 +439,11 @@ struct Call :Expr{ } }; -struct Global :Node{ +class Global :ASTNode{ list ids; list funcs; virtual void code(FILE *fp){ - Node::code(fp); + ASTNode::code(fp); if (!ids.empty()){ int width = 0; fprintf(fp, ".data\n"); @@ -442,4 +467,34 @@ struct Global :Node{ } }; -#endif \ No newline at end of file +#endif + +#ifndef __VISITOR_H_ + +class Visitor { +public: + virtual void visit(ASTNode *node) = 0; +}; + +class BinaryExpr : Visitor { +public: + virtual void visit(BinaryExpr *expr) { + + } +}; + +class UnaryExprVisitor : Visitor { +public: + virtual void visit(UnaryExpr *expr) { + + } +}; + +class StmtVisitor : Visitor{ +public: + virtual void visit(Stmt *stmt) { + + } +}; + +#endif // !__VISITOR_H_ diff --git a/Parser/lexer.h b/Parser/lexer.h index a2f68b6..939aa67 100644 --- a/Parser/lexer.h +++ b/Parser/lexer.h @@ -114,7 +114,7 @@ class ReadBuffer { fclose(file); } void open(char *filename) { - file = fopen(filename, "rb"); + fopen_s(&file, filename, "rb"); } char operator[](int i) { return buf[(front + i) % size]; diff --git a/Parser/main.cpp b/Parser/main.cpp index a1a6aa1..2f3f1a6 100644 --- a/Parser/main.cpp +++ b/Parser/main.cpp @@ -6,7 +6,7 @@ void main(){ FILE *fp = &file; Parser *p = new Parser(); printf("开始语法分析\n"); - Node *st = p->parse("Text.txt"); + ASTNode *st = p->parse("Text.txt"); printf("语法分析结束\n"); printf("编译开始\n"); printf(" line stmt\n"); @@ -20,5 +20,5 @@ void main(){ //parse(fp); //printf("SLR(1)语法分析结束\n"); //fclose(fp); - cin >> a; + //cin >> a; } \ No newline at end of file diff --git a/Parser/parser.h b/Parser/parser.h index e17c80f..e1ed4c3 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -211,10 +211,10 @@ class Parser{ Stmt* stmt_assign(){ Assign *a = new Assign; a->line = lexer->line; - a->E1 = getId(); + a->id = getId(); match(ID); match('='); - a->E2 = expr_expr(); + a->expr = expr_expr(); return a; } // 条件语句 @@ -223,15 +223,15 @@ class Parser{ i->line = lexer->line; match(IF); match('('); - i->C = expr_cond(); + i->cond = expr_cond(); match(')'); - i->S1 = stmt(); + i->body = stmt(); if (s->kind == ELSE){ Else *e = new Else; match(ELSE); e->line = i->line; - e->C = i->C; - e->S1 = i->S1; + e->C = i->cond; + e->S1 = i->body; e->S2 = stmt(); return e; } @@ -243,11 +243,11 @@ class Parser{ w->line = lexer->line; match(WHILE); match('('); - w->C = expr_cond(); + w->cond = expr_cond(); match(')'); Break::cur.push(w); Continue::cur.push(w);// continue 跳转到语句开头执行 - w->S1 = stmt(); + w->body = stmt(); Continue::cur.pop(); Break::cur.pop(); return w; @@ -258,12 +258,12 @@ class Parser{ match(DO); Break::cur.push(d); Continue::cur.push(d);// continue 跳转到语句开头执行 - d->S1 = stmt(); + d->body = stmt(); Continue::cur.pop(); Break::cur.pop(); match(WHILE); match('('); - d->C = expr_cond(); + d->cond = expr_cond(); match(')'); match(';'); return d; @@ -277,11 +277,11 @@ class Parser{ match(';'); f->C = expr_cond(); match(';'); - f->S2 = stmt_assign(); + f->step = stmt_assign(); match(')'); Break::cur.push(f); - Continue::cur.push(f->S2);// continue直接跳转到第二条赋值语句开头执行 - f->S3 = stmt(); + Continue::cur.push(f->step);// continue直接跳转到第二条赋值语句开头执行 + f->body = stmt(); Continue::cur.pop(); Break::cur.pop(); return f; @@ -291,7 +291,7 @@ class Parser{ Case *c = new Case; c->line = lexer->line; match(CASE); - c->E = expr_expr(); + c->expr = expr_expr(); while (s->kind != END){ Integer *i = (Integer*)s; match(INT); @@ -330,11 +330,11 @@ class Parser{ } // 表达式语句 BinaryExpr* expr_binary() { - Expr* pL = expr_binary(); + ExprAST* pL = expr_binary(); while (s->kind) { Word* w = (Word*)s; if (compare(w->word, pL->opt)) { - Expr* pR = expr_binary(); + ExprAST* pR = expr_binary(); } pL = new BinaryExpr(w->word, pL, pR); } @@ -354,9 +354,9 @@ class Parser{ } return u; } - Expr* expr_factor() + ExprAST* expr_factor() { - Expr* e = nullptr; + ExprAST* e = nullptr; switch (s->kind){ case '(': match('('); e = expr_binary(); match(')'); break; case ID: @@ -374,7 +374,7 @@ class Parser{ return e; } // 函数调用 - Expr* expr_call(){ + ExprAST* expr_call(){ Call *c = new Call; c->line = lexer->line; c->func = (Function*)getId()->s; @@ -382,7 +382,7 @@ class Parser{ // 函数调用 match('('); while (s->kind == ID || s->kind == NUM){ - Expr *e = expr_binary(); + ExprAST *e = expr_binary(); if (e)c->args.push_back(e); if (s->kind == ',') match(','); } @@ -403,7 +403,7 @@ class Parser{ delete symbols; delete globol; } - Node* parse(char *filename){ + ASTNode* parse(char *filename){ lexer->open(filename); s = lexer->scan();// 预读一个词法单元,以便启动语法分析 node(); From 964700cadf075bbfe512f0aaf7551000c1bb9b5c Mon Sep 17 00:00:00 2001 From: mbs0221 Date: Tue, 18 Feb 2020 23:48:43 +0800 Subject: [PATCH 20/22] update project --- Parser/Parser.vcxproj | 2 + Parser/Parser.vcxproj.filters | 6 + Parser/inter.cpp | 242 ++++++++++++++++ Parser/inter.h | 522 ++++++++++------------------------ Parser/lexer.h | 25 +- Parser/main.cpp | 2 +- Parser/parser.cpp | 329 +++++++++++++++++++++ Parser/parser.h | 426 +++++---------------------- 8 files changed, 794 insertions(+), 760 deletions(-) create mode 100644 Parser/inter.cpp create mode 100644 Parser/parser.cpp diff --git a/Parser/Parser.vcxproj b/Parser/Parser.vcxproj index 5a64c7e..6da8311 100644 --- a/Parser/Parser.vcxproj +++ b/Parser/Parser.vcxproj @@ -72,7 +72,9 @@ + + diff --git a/Parser/Parser.vcxproj.filters b/Parser/Parser.vcxproj.filters index 158a7f2..1632e03 100644 --- a/Parser/Parser.vcxproj.filters +++ b/Parser/Parser.vcxproj.filters @@ -45,5 +45,11 @@ 婧愭枃浠 + + 婧愭枃浠 + + + 婧愭枃浠 + \ No newline at end of file diff --git a/Parser/inter.cpp b/Parser/inter.cpp new file mode 100644 index 0000000..6cae8a2 --- /dev/null +++ b/Parser/inter.cpp @@ -0,0 +1,242 @@ +#include "inter.h" + +void Stmt::Codegen(FILE * fp) +{ + ASTNode::Codegen(fp); + printf("[%04d]", line); +} + +void Block::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + //printf("stmts\n"); + //list::iterator iter; + //for (iter = Ss.begin(); iter != Ss.end(); iter++) { + // (*iter)->Codegen(fp); + //} +} + +void ExprAST::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); +} + +void BinaryExprAST::Codegen(FILE * fp) +{ + ExprAST::Codegen(fp); + pL->Codegen(fp); + pR->Codegen(fp); +} + +void UnaryExprAST::Codegen(FILE * fp) +{ + ExprAST::Codegen(fp); + E1->Codegen(fp); +} + +void VariableExprAST::Codegen(FILE * fp) +{ + ExprAST::Codegen(fp); + /*char *width = type == Type::Int ? "dw" : "b"; + if (global) { + fprintf(fp, "\tload%s $%d %s\n", width, label, name->getName()); + } + else { + fprintf(fp, "\tload%s $%d %s\n", width, label, name->getName()); + }*/ +} + +void AssignExprAST::Codegen(FILE * fp) +{ + ExprAST::Codegen(fp); + expr->Codegen(fp); + /*if (id->global) { + fprintf(fp, "\tstore %s $%d\n", id->getName(), expr->label); + } + else { + fprintf(fp, "\tstore %s $%d\n", id->getName(), expr->label); + }*/ +} + +void ConstantExprAST::Codegen(FILE * fp) +{ + ExprAST::Codegen(fp); + char width = s->value > 256 ? 'w' : 'b'; + fprintf(fp, "\tload%c $%d %d\n", width, label, s->value); +} + +void CallExprAST::Codegen(FILE * fp) +{ + ExprAST::Codegen(fp); + printf("call\n"); + // 参数计算 + vector::iterator iter; + for (ExprAST* expr : args) { + expr->Codegen(fp); + } + // 传递参数 + reverse(args.begin(), args.end()); + for (ExprAST* expr : args) { + fprintf(fp, "\tparam $%d\n", expr->label); + } + // 调用语句 + fprintf(fp, "\tcall %s\n", callee); +} + +void Decl::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + /*fprintf(fp, "\tdata\n"); + list::iterator iter; + for (iter = ids.begin(); iter != ids.end(); iter++) { + printf("\t$%s [%d]\n", (*iter)->getName(), (*iter)->getWidth()); + fprintf(fp, "\t\t$%s [%d]\n", (*iter)->getName(), (*iter)->getWidth()); + } + printf("data\n"); + fprintf(fp, "\tdata\n");*/ +} + +void IfElse::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + cond->Codegen(fp); + body_t->next = newlabel(); + fprintf(fp, "jz L%d:\n", body_t->next); + // True + body_t->Codegen(fp); + next = newlabel(); + fprintf(fp, "jmp L%d:\n", next); + fprintf(fp, "L%d:\n", body_t->next); + // False + if (body_f) { + body_f->next = newlabel(); + body_f->Codegen(fp); + } + fprintf(fp, "L%d:\n", next); +} + +void WhileDo::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + begin = newlabel(); + next = newlabel(); + body->next = begin; + fprintf(fp, "L%d:\n", begin); + cond->Codegen(fp); + fprintf(fp, "jz L:\n", next);// False跳转 + body->Codegen(fp); + fprintf(fp, "\tjmp L%d\n", begin); + fprintf(fp, "L%d:\n", next); +} + +void DoWhile::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + begin = newlabel(); + body->next = begin; + fprintf(fp, "L%d:\n", begin); + body->Codegen(fp); + cond->Codegen(fp); + fprintf(fp, "jnz L%d:\n", begin);// True跳转 +} + +void For::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + begin = newlabel(); + next = newlabel(); + step->begin = newlabel(); + step->next = newlabel(); + body->next = begin; + init->Codegen(fp); + fprintf(fp, "L%d:\n", begin); + cond->Codegen(fp); + fprintf(fp, "L%d:\n", cond->label); // False跳转 + body->Codegen(fp); + fprintf(fp, "L%d:\n", step->begin); + step->Codegen(fp); + fprintf(fp, "\tjmp L%d\n", begin); + fprintf(fp, "L%d:\n", next); +} + +void Switch::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + expr->Codegen(fp); + for (Case cs : cases) { + fprintf(fp, "= $%d $%d\n", expr->label, cs.first); + fprintf(fp, "jne L%d", cs.second->begin); + cs.second->Codegen(fp); + fprintf(fp, "L%d", cs.second->next); + } +} + +void Break::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + fprintf(fp, "\tjmp L%d\n", stmt->next); +} + +void Continue::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + fprintf(fp, "\tjmp L%d\n", next->begin); +} + +void Throw::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + fprintf(fp, "\tjmp L%d\n", exception->kind); +} + +void TryCatch::Codegen(FILE * fp) +{ + Stmt::Codegen(fp); + // 需要异常处理的程序 + pTry->Codegen(fp); + fprintf(fp, "\tjmp L%d\n", pCatch->next); + // 异常处理程序 + fprintf(fp, "L%d:\n", pCatch->begin); + pCatch->Codegen(fp); + fprintf(fp, "L%d:\n", pCatch->next); + // 扫尾操作 + pFinally->Codegen(fp); +} + +void FunctionAST::Codegen(FILE * fp) +{ + //fprintf(fp, "proc %s:\n", word.c_str()); + //list::iterator iter; + //int width = type->width; + //for (iter = params->ids.begin(); iter != params->ids.end(); iter++){ + // (*iter)->offset = width; + // (*iter)->global = false; + // fprintf(fp, "\t;%s @%d\n", (*iter)->getName(), width); + // width += (*iter)->getWidth(); + //} + //width = 0; + //Symbols *table = symbols; + //for (table = symbols; table != nullptr; table = table->next){ + // for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ + // (*iter)->offset = width; + // (*iter)->global = false; + // fprintf(fp, "\t;%s @%d\n", (*iter)->getName(), width); + // width += (*iter)->getWidth(); + // } + //} + //fprintf(fp, "\tsub $sp %d\n", width); + //width = 0; + //for (table = params; table != nullptr; table = table->next){ + // for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ + // (*iter)->offset = width; + // (*iter)->global = false; + // width += (*iter)->getWidth(); + // } + //} + //body->code(fp); + //fprintf(fp, "endp\n"); +} + +void PrototypeAST::Codegen(FILE * fp) +{ +} diff --git a/Parser/inter.h b/Parser/inter.h index de87fd7..accd641 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -11,490 +11,256 @@ class Visitor; class ASTNode{ friend class Visitor; public: - virtual void code(FILE *fp){ - - } -}; - -class Nodes :ASTNode{ - list nodes; -public: - virtual void code(FILE *fp){ - list::iterator iter; - for (iter = nodes.begin(); iter != nodes.end(); iter++){ - (*iter)->code(fp); - } - } + virtual void Codegen(FILE *fp) = 0; }; //语句 -class Stmt :ASTNode{ +class Stmt : ASTNode{ +public: int line; int begin, next; static int label; -public: static int newlabel(){ return label++; } - virtual void code(FILE *fp){ - ASTNode::code(fp); - printf("[%04d]", line); - } + virtual void Codegen(FILE *fp); }; int Stmt::label = 0; //语句块 -class Stmts :Stmt{ - list Ss; +class Block : public Stmt{ + vector block; public: - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("stmts\n"); - list::iterator iter; - for (iter = Ss.begin(); iter != Ss.end(); iter++){ - (*iter)->code(fp); - } - } + Block(vector &block) : block(block) { } + virtual void Codegen(FILE *fp); }; //表达式 -class ExprAST : Stmt{ +class ExprAST : public Stmt{ +public: + Type *type; int label; static int count; -public: ExprAST() { label = count++; } - virtual void code(FILE *fp){ - ASTNode::code(fp); - } + virtual void Codegen(FILE *fp); }; int ExprAST::count = 0; -// 双目表达式 -class BinaryExpr : ExprAST { - Word opt; +class BinaryExprAST : public ExprAST { + int opt; ExprAST *pL, *pR; public: - BinaryExpr(Word &opt, ExprAST *pL, ExprAST *pR) : opt(opt), pL(pL), pR(pR) { ; } - virtual void code(FILE *fp) override { - ExprAST::code(fp); - } + BinaryExprAST(int opt, ExprAST *pL, ExprAST *pR) + : opt(opt), pL(pL), pR(pR) { } + virtual void Codegen(FILE *fp); }; -// 单目表达式 -class UnaryExpr :ExprAST{ - Word opt; +class UnaryExprAST : public ExprAST{ + int opt; ExprAST *E1; public: - UnaryExpr(Word &opt, ExprAST *E1) :opt(opt), E1(E1){ } - virtual void code(FILE *fp){ - ExprAST::code(fp); - } + UnaryExprAST(int opt, ExprAST *E1) + : opt(opt), E1(E1){ } + virtual void Codegen(FILE *fp); }; -// ID -class Id :ExprAST{ - Type *type; - Word *name; - int offset; - bool global; +class VariableExprAST : public ExprAST { + string name; public: - Id(Type *type, Word *name) : type(type), name(name){ } - const char* getName() { return name->word.c_str(); } - const char* getTypeName() { return type->word.c_str(); } - int getWidth() { return type->width; } - virtual void code(FILE *fp){ - ExprAST::code(fp); - char *width = type == Type::Int ? "dw" : "b"; - if (global){ - fprintf(fp, "\tload%s $%d %s\n", width, label, name->getName()); - }else{ - fprintf(fp, "\tload%s $%d %s\n", width, label, name->getName()); - } - } + VariableExprAST(const string &name) : name(name){ } + void Codegen(FILE *fp); +}; + +class AssignExprAST : public VariableExprAST { + ExprAST *expr; +public: + AssignExprAST(const string &name, ExprAST *expr) + : VariableExprAST(name), expr(expr) { } + void Codegen(FILE *fp); }; -class Constant : ExprAST{ +class ConstantExprAST : public ExprAST { Integer *s; public: - Constant(Integer *s) : s(s){ } - virtual void code(FILE *fp){ - ExprAST::code(fp); - char width = s->value > 256 ? 'w' : 'b'; - fprintf(fp, "\tload%c $%d %d\n", width, label, s->value); - } + ConstantExprAST(Integer *s) : s(s) { } + void Codegen(FILE *fp); }; -class Decl :Stmt{ - list ids; +class AccessExprAST : public VariableExprAST { + ExprAST *loc; public: - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("data\n"); - fprintf(fp, "\tdata\n"); - list::iterator iter; - for (iter = ids.begin(); iter != ids.end(); iter++){ - printf("\t$%s [%d]\n", (*iter)->getName(), (*iter)->getWidth()); - fprintf(fp, "\t\t$%s [%d]\n", (*iter)->getName(), (*iter)->getWidth()); - } - printf("data\n"); - fprintf(fp, "\tdata\n"); - } + AccessExprAST(const string &name, ExprAST *loc) + : VariableExprAST(name), loc(loc) { } }; -class Assign :Stmt{ - Id *id; - ExprAST *expr; +//class MemberExpr : public ExprAST { +// string name; +// ExprAST *index; +//public: +// MemberExpr(const string name, ExprAST *index) +// : name(name), index(index) { } +//}; +// +//class PointerExpr : public ExprAST { +// string name; +// ExprAST *index; +//public: +// PointerExpr(const string name, ExprAST *index) +// : name(name), index(index) { } +//}; + +class CallExprAST : public ExprAST { + string callee; + vector args; public: - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("assign\n"); - expr->code(fp); - if (id->global){ - fprintf(fp, "\tstore %s $%d\n", id->getName(), expr->label); - }else{ - fprintf(fp, "\tstore %s $%d\n", id->getName(), expr->label); - } - } + CallExprAST() { args.clear(); } + CallExprAST(const string &callee, vector &args) + : callee(callee), args(args) { ; } + void Codegen(FILE *fp); }; -class If :Stmt{ - ExprAST *cond; - Stmt *body; +class Decl : Stmt{ + list ids; public: - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("if\n"); - next = newlabel(); - body->next = next; - // 计算表达式 - cond->code(fp); - // 为False跳转 - fprintf(fp, "jz L%d", next);// False跳转 - body->code(fp); - fprintf(fp, "L%d:\n", next); - } + void Codegen(FILE *fp); }; -class IfElse :Stmt{ +class IfElse : public Stmt{ ExprAST *cond; Stmt *body_t; Stmt *body_f; public: - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("if-else\n"); - body_t->next = newlabel(); - body_f->next = newlabel(); - // 计算表达式 - cond->code(fp); - // 为False跳转 - fprintf(fp, "jz L%d:\n", next);// False跳转 - body_t->code(fp); - fprintf(fp, "\tjmp L%d\n", next); - fprintf(fp, "L%d:\n", next); - body_f->code(fp); - fprintf(fp, "L%d:\n", body_t->next); - } + IfElse(ExprAST *cond, Stmt *body_t, Stmt *body_f) + : cond(cond), body_t(body_t), body_f(body_f) { } + void Codegen(FILE *fp); }; -class While :Stmt{ +class WhileDo : public Stmt{ ExprAST *cond; Stmt *body; public: - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("while\n"); - begin = newlabel(); - next = newlabel(); - body->next = begin; - fprintf(fp, "L%d:\n", begin); - cond->code(fp); - fprintf(fp, "jz L:\n", next);// False跳转 - body->code(fp); - fprintf(fp, "\tjmp L%d\n", begin); - fprintf(fp, "L%d:\n", next); - } + WhileDo(ExprAST *cond, Stmt *body) :cond(cond), body(body) { } + void Codegen(FILE *fp); }; -class Do :Stmt{ +class DoWhile : public Stmt{ ExprAST *cond; Stmt *body; public: - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("do-while\n"); - begin = newlabel(); - body->next = begin; - fprintf(fp, "L%d:\n", begin); - body->code(fp); - cond->code(fp); - fprintf(fp, "jnz L%d:\n", begin);// True跳转 - } + DoWhile(ExprAST *cond, Stmt *body) :cond(cond), body(body) { } + void Codegen(FILE *fp); }; -class For : Stmt{ - Stmt *init; - ExprAST *cond; - Stmt *step; +class For : public Stmt{ + ExprAST *init, *cond, *step; Stmt *body; public: - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("for\n"); - begin = newlabel(); - next = newlabel(); - step->begin = newlabel(); - step->next = newlabel(); - body->next = begin; - init->code(fp); - fprintf(fp, "L%d:\n", begin); - cond->code(fp); - fprintf(fp, "L%d:\n", cond->label); // False跳转 - body->code(fp); - fprintf(fp, "L%d:\n", step->begin); - step->code(fp); - fprintf(fp, "\tjmp L%d\n", begin); - fprintf(fp, "L%d:\n", next); - } + For(ExprAST *init, ExprAST *cond, ExprAST *step, Stmt *body) + : init(init), cond(cond), step(step), body(body) { } + void Codegen(FILE *fp); }; -class Case :Stmt{ +typedef pair Case; + +class Switch : public Stmt { ExprAST *expr; - map Ss; + vector cases; public: - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("case\n"); - fprintf(fp, "jmp L%d\n", begin); - map::iterator iter; - for (iter = Ss.begin(); iter != Ss.end(); iter++){ - fprintf(fp, "L%d:\n", iter->second->begin); - iter->second->code(fp); - } - fprintf(fp, "L%d:\n", begin); - expr->code(fp); - for (iter = Ss.begin(); iter != Ss.end(); iter++){ - fprintf(fp, "L%d:\n", iter->second->begin); - fprintf(fp, "= $%d $%d #%d\n", expr->label, iter->first); - iter->second->code(fp); - } - } + Switch(ExprAST *expr, vector> &cases) + : expr(expr), cases(cases) { } + void Codegen(FILE *fp); }; -class Break :Stmt{ +class Break : public Stmt{ Stmt *stmt; - static stack cur; public: - Break(){ - stmt = Break::cur.top(); - } - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("break\n", stmt->next); - fprintf(fp, "\tjmp L%d\n", stmt->next); - } + Break(Stmt *next) : stmt(next) { } + void Codegen(FILE *fp); }; -stack Break::cur = stack(); - -class Continue :Stmt{ - Stmt *stmt; - static stack cur; +class Continue : public Stmt{ + Stmt *next; public: - Continue(){ - stmt = Continue::cur.top(); - } - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("continue\n", stmt->begin); - fprintf(fp, "\tjmp L%d\n", stmt->begin); - } + Continue(Stmt *next) : next(next) { } + void Codegen(FILE *fp); }; -stack Continue::cur = stack(); - -// 异常处理程序 -class Throw : Stmt { - Type* exception;// 抛出异常 +class Throw : public Stmt { + Type* exception; public: Throw() { exception = nullptr; } - virtual void code(FILE *fp) { - Stmt::code(fp); - // 跳转异常处理程序 - fprintf(fp, "\tjmp L%d\n", exception->kind); - } + void Codegen(FILE *fp); }; -class TryCatch : Stmt{ +class TryCatch : public Stmt{ Stmt *pTry, *pCatch, *pFinally; public: - TryCatch() { - pTry = pCatch = pFinally = nullptr; - } - TryCatch(Stmt* pTry, Stmt* pCatch, Stmt* pFinally) :pTry(pTry), pCatch(pCatch), pFinally(pFinally) { } - virtual void code(FILE *fp) { - Stmt::code(fp); - // 需要异常处理的程序 - pTry->code(fp); - fprintf(fp, "\tjmp L%d\n", pCatch->next); - // 异常处理程序 - fprintf(fp, "L%d:\n", pCatch->begin); - pCatch->code(fp); - fprintf(fp, "L%d:\n", pCatch->next); - // 扫尾操作 - pFinally->code(fp); - } + TryCatch(Stmt* pTry, Stmt* pCatch, Stmt* pFinally) + : pTry(pTry), pCatch(pCatch), pFinally(pFinally) { } + void Codegen(FILE *fp); }; // -------------符号表----------- - -class Symbols{ - int id; - static int count; - list ids; - Symbols *prev, *next; -public: - Symbols(){ - id = count++; - ids.clear(); - prev = nullptr; - next = nullptr; - } -}; - -int Symbols::count = 0; +typedef map SymbolTable; + +//class Symbols{ +//public: +// int id; +// static int count; +// list ids; +// Symbols *prev, *next; +// Symbols(){ +// id = count++; +// ids.clear(); +// prev = nullptr; +// next = nullptr; +// } +//}; +// +//int Symbols::count = 0; // -------------函数----------- - -class Function : Word{ +class ParameterAST { Type *type; - Symbols *params; - Symbols *symbols; - Stmt* body; + string name; public: - Function(string name, Type *type) :Word(FUNCTION, name), type(type){ - kind = FUNCTION; - params = new Symbols; - symbols = new Symbols; - } - virtual void code(FILE *fp){ - fprintf(fp, "proc %s:\n", word.c_str()); - list::iterator iter; - int width = type->width; - for (iter = params->ids.begin(); iter != params->ids.end(); iter++){ - (*iter)->offset = width; - (*iter)->global = false; - fprintf(fp, "\t;%s @%d\n", (*iter)->getName(), width); - width += (*iter)->getWidth(); - } - width = 0; - Symbols *table = symbols; - for (table = symbols; table != nullptr; table = table->next){ - for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ - (*iter)->offset = width; - (*iter)->global = false; - fprintf(fp, "\t;%s @%d\n", (*iter)->getName(), width); - width += (*iter)->getWidth(); - } - } - fprintf(fp, "\tsub $sp %d\n", width); - width = 0; - for (table = params; table != nullptr; table = table->next){ - for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ - (*iter)->offset = width; - (*iter)->global = false; - width += (*iter)->getWidth(); - } - } - body->code(fp); - fprintf(fp, "endp\n"); - } + ParameterAST(Type *type, string name) : type(type), name(name) { } }; -class Call :ExprAST{ - list args; - Function *func; +class PrototypeAST { + Type *type; + string name; + vector args; public: - Call() { args.clear(); } - Call(int line, Function *func) :ExprAST(), func(func) { ; } - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("call\n"); - // 参数计算 - list::iterator iter; - for (iter = args.begin(); iter != args.end(); iter++){ - (*iter)->code(fp); - } - // 传递参数 - reverse(args.begin(), args.end()); - for (iter = args.begin(); iter != args.end(); iter++){ - fprintf(fp, "\tparam $%d\n", (*iter)->label); - } - // 调用语句 - fprintf(fp, "\tcall %s %d\n", func->word.c_str(), args.size()); - } + PrototypeAST(Type *type, const string &name, vector &args) + : type(type), name(name), args(args) { } + void Codegen(FILE * fp); }; -class Global :ASTNode{ - list ids; - list funcs; - virtual void code(FILE *fp){ - ASTNode::code(fp); - if (!ids.empty()){ - int width = 0; - fprintf(fp, ".data\n"); - list::iterator iter; - for (iter = ids.begin(); iter != ids.end(); iter++){ - (*iter)->offset = width; - (*iter)->global = true; - fprintf(fp, "\t%s %s\n", (*iter)->getTypeName(), (*iter)->getName()); - width += (*iter)->getWidth(); - } - } - fprintf(fp, ".stack\n"); - fprintf(fp, "\t\db dup(0x1000)\n"); - if (!funcs.empty()){ - fprintf(fp, ".code\n"); - list::iterator iter2; - for (iter2 = funcs.begin(); iter2 != funcs.end(); iter2++){ - (*iter2)->code(fp); - } - } - } -}; - -#endif - -#ifndef __VISITOR_H_ - -class Visitor { +class FunctionAST { + PrototypeAST *proto; + Stmt *body; public: - virtual void visit(ASTNode *node) = 0; + FunctionAST(PrototypeAST *proto, Stmt *body) : proto(proto), body(body) { } + void Codegen(FILE * fp); }; -class BinaryExpr : Visitor { +class Global : ASTNode { + map symbols; public: - virtual void visit(BinaryExpr *expr) { - + void putId(string name, Type* type) { + symbols[name] = type; } -}; - -class UnaryExprVisitor : Visitor { -public: - virtual void visit(UnaryExpr *expr) { - + Type* getId(string name) { + return symbols[name]; } -}; - -class StmtVisitor : Visitor{ -public: - virtual void visit(Stmt *stmt) { - + virtual void code(FILE *fp){ + ASTNode::Codegen(fp); } }; -#endif // !__VISITOR_H_ +#endif // !__INTER_H_ diff --git a/Parser/lexer.h b/Parser/lexer.h index 939aa67..698f3fa 100644 --- a/Parser/lexer.h +++ b/Parser/lexer.h @@ -15,10 +15,11 @@ using namespace std; enum Tag{ - IF = 256, THEN, ELSE, DO, WHILE, FOR, CASE, BREAK, CONTINUE, TRY, CATCH, FINALLY, THROW, + IF = 256, THEN, ELSE, DO, WHILE, FOR, SWITCH, CASE, BREAK, CONTINUE, TRY, CATCH, FINALLY, THROW, BASIC, INT, CHAR, END, ID, NUM, FUNCTION, + ASSIGN, // ASSIGN AND, OR, NOT, // LOGIC BIT_AND, BIT_OR, BIT_NOT, // BIT LOGIC EQ, NEQ, // REL @@ -38,20 +39,6 @@ struct Token{ s << kind; return s.str(); } - virtual string code(){ - ostringstream s; - char *keywords[] = { - "IF", "THEN", "ELSE", "DO", "WHILE", "FOR", - "CASE", "BREAK", "CONTINUE", - "TRY", "CATCH", "FINALLY", "THROW", - "ID", "BASIC", "INT", "CHAR", "END" - }; - if (kind >=IF && kind <= END) - s << keywords[kind - IF]; - else - s << (char)kind; - return s.str(); - } }; struct Word :Token{ @@ -259,16 +246,16 @@ class Lexer{ case '>': case '=': buffer.pop(); - return words[ch];// 运算符 + return words[ch]; break; default: break; } ch[1] = '\0'; if (words.find(ch) != words.end()) { - return words[ch];// 运算符 + return words[ch]; } - return new Token(ch[0]);//普通字符 + return new Token(ch[0]); } Token *scan() { @@ -284,7 +271,7 @@ class Lexer{ str.push_back(ch); ch = buffer.peak(); buffer.read(); - } while (isalnum(ch) || ch == '_'); //1状态 + } while (isalnum(ch) || ch == '_'); if (words.find(str) == words.end()){ return new Word(ID, str); } diff --git a/Parser/main.cpp b/Parser/main.cpp index 2f3f1a6..f4464b4 100644 --- a/Parser/main.cpp +++ b/Parser/main.cpp @@ -11,7 +11,7 @@ void main(){ printf("编译开始\n"); printf(" line stmt\n"); fopen_s(&fp, "data.s", "w"); - st->code(fp); + st->Codegen(fp); fclose(fp); printf("编译结束\n"); delete p; diff --git a/Parser/parser.cpp b/Parser/parser.cpp new file mode 100644 index 0000000..453f14b --- /dev/null +++ b/Parser/parser.cpp @@ -0,0 +1,329 @@ +#include "parser.h" + +void Parser::parseBlocks() +{ + while (s->kind == BASIC) { + parseDefinition(); + } +} + +void Parser::parseDefinition() +{ + Type *type = (Type*)s; + match(BASIC); + Word *word = (Word*)s; + match(ID); + if (word->kind != '(') { + top_scope[word->word] = type; + while (s->kind == ',') { + match(','); + top_scope[word->word] = type; + match(ID); + } + match(';'); + return; + } + FunctionAST *f = parseFunction(word->word, type); +} + +PrototypeAST * Parser::parsePrototype(string name, Type * type) +{ + vector args; + match('('); + int offset = 0; + if (s->kind == BASIC) { + Type *type = (Type*)s; + match(BASIC); + args.push_back(new ParameterAST(type, ((Word*)s)->word)); + match(ID); + while (s->kind == ',') { + match(','); + match(BASIC); + args.push_back(new ParameterAST(type, ((Word*)s)->word)); + match(ID); + } + } + match(')'); + return new PrototypeAST(type, name, args); +} + +FunctionAST * Parser::parseFunction(string name, Type * type) +{ + + PrototypeAST *proto = parsePrototype(name, type); + if (proto == nullptr) return 0; + + if (Stmt *body = parseBlock()) + return new FunctionAST(proto, body); + + return 0; +} + +Stmt * Parser::parseStmt() +{ + Stmt *st = nullptr; + // 语法分析 + switch (s->kind) { + case BASIC:st = parseDeclaration(); break; + case ID:parseExpression(); break; + case IF:st = parseIfElse(); break; + case WHILE:st = parseWhileDo(); break; + case DO:st = parseDoWhile(); break; + case FOR:st = parseFor(); break; + case CASE:st = parseSwitch(); break; + case BREAK:st = parseBreak(); break; + case CONTINUE:st = parseContinue(); break; + case TRY:st = parseTryCatch(); break; + case ';':match(';'); break; + case '{':st = parseBlock(); break; + default:match(s->kind); break; + } + return st; +} + +Stmt * Parser::parseBlock() +{ + vector block; + match('{'); + while (s->kind != '}') { + Stmt *st = parseStmt(); + if (st) { + block.push_back(st); + } + } + match('}'); + return new Block(block); +} + +Stmt * Parser::parseDeclaration() +{ + Type *type = (Type*)s; + match(BASIC); + top_scope[((Word*)s)->word] = type; + match(ID); + while (s->kind == ',') { + match(','); + top_scope[((Word*)s)->word] = type; + match(ID); + } + match(';'); +} + +Stmt * Parser::parseIfElse() +{ + match(IF); + match('('); + ExprAST *cond = parseExpression(); + match(')'); + Stmt *body_t = parseStmt(); + if (s->kind == ELSE) { + match(ELSE); + Stmt *body_f = parseStmt(); + return new IfElse(cond, body_t, body_f); + } + return new IfElse(cond, body_t, nullptr); +} + +Stmt * Parser::parseWhileDo() +{ + match(WHILE); + match('('); + ExprAST *cond = parseExpression(); + match(')'); + Stmt *body = parseStmt(); + return new WhileDo(cond, body); +} + +Stmt * Parser::parseDoWhile() +{ + match(DO); + Stmt *body = parseStmt(); + blocks.pop(); + match(WHILE); + match('('); + ExprAST *cond = parseExpression(); + match(')'); + match(';'); + return new DoWhile(cond, body); +} + +Stmt * Parser::parseFor() +{ + match(FOR); + match('('); + ExprAST *init = parseExpression(); + match(';'); + ExprAST *cond = parseExpression(); + match(';'); + ExprAST *step = parseExpression(); + match(')'); + Stmt *body = parseStmt(); + return new For(init, cond, step, body); +} + +Stmt * Parser::parseSwitch() +{ + vector cases; + match(SWITCH); + match('('); + ExprAST *expr = parseExpression(); + match(')'); + match(CASE); + while (s->kind == CASE) { + Integer *i = (Integer*)s; + match(INT); + match(':'); + cases.push_back(Case(i->value, parseStmt())); + } + match(END); + return new Switch(expr, cases); +} + +Stmt * Parser::parseBreak() +{ + Break *st = new Break(blocks.top()); + match(BREAK); + match(';'); + return st; +} + +Stmt * Parser::parseContinue() +{ + Continue *st = new Continue(blocks.top()); + st->line = lexer->line; + match(CONTINUE); + match(';'); + return st; +} + +Stmt * Parser::parseThrow() +{ + match(THROW); +} + +Stmt * Parser::parseTryCatch() +{ + match(TRY); + Stmt* pTry = parseStmt(); + match(CATCH); + Stmt* pCatch = parseStmt(); + match(FINALLY); + Stmt* pFinnaly = parseStmt(); + return new TryCatch(pTry, pCatch, pFinnaly); +} + +ExprAST * Parser::parseExpression() +{ + ExprAST *lhs = parsePrimary(); + if (!lhs) return 0; + + return parseBinaryExpr(0, lhs); +} + +ExprAST * Parser::parseBinaryExpr(int ExprPrec, ExprAST * lhs) +{ + // If this is a binop, find its precedence. + while (true) { + int TokPrec = GetTokPrecedence(); + + // If this is a binop that binds at least as tightly as the current binop, + // consume it, otherwise we are done. + if (TokPrec < ExprPrec) + return lhs; + + // Okay, we know this is a binop. + int opt = s->kind; + match(s->kind); + + // Parse the primary expression after the binary operator. + ExprAST *rhs = parsePrimary(); + if (!rhs) return 0; + + // If BinOp binds less tightly with RHS than the operator after RHS, let + // the pending operator take RHS as its LHS. + int NextPrec = GetTokPrecedence(); + if (TokPrec < NextPrec) { + rhs = parseBinaryExpr(TokPrec + 1, rhs); + if (!rhs) return 0; + } + + // Merge LHS/RHS. + lhs = new BinaryExprAST(opt, lhs, rhs); + } +} + +ExprAST * Parser::parsePrimary() +{ + // primary ::= id | num | unary + switch (s->kind) { + case ID: return parseIdentifierExpr(); + case NUM: return parseConstantExpr(); + case '(': return parseBracketsExpr(); + case INC: + case DEC: + case '!': + case '~': + case '-': return parseUnaryExpr(); + default: return 0; + } +} + +ExprAST * Parser::parseIdentifierExpr() +{ + // id ::= id | assign | call + string name = ((Word*)s)->word; + match(ID); + // assign + if (s->kind == '=') { + match('='); + ExprAST *expr = parseExpression(); + return new AssignExprAST(name, expr); + } + // call + if (s->kind == '(') { + match('('); + vector args; + if (s->kind != ')') { + while (true) { + ExprAST *arg = parseExpression(); + if (arg == nullptr) + return 0; + args.push_back(arg); + + if (s->kind == ')') + break; + + if (s->kind != ',') + return 0; + match(','); + } + match(')'); + return new CallExprAST(name, args); + } + } + return new VariableExprAST(name); +} + +ExprAST * Parser::parseConstantExpr() +{ + ExprAST *Result = new ConstantExprAST((Integer*)s); + match(NUM); + return Result; +} + +ExprAST * Parser::parseBracketsExpr() +{ + match('('); + ExprAST *e = parseExpression(); + if (!e) return 0; + if (s->kind != ')') return 0; + match(')'); + return e; +} + +ExprAST * Parser::parseUnaryExpr() +{ + int opt = s->kind; + match(opt); + return new UnaryExprAST(opt, parseExpression()); +} diff --git a/Parser/parser.h b/Parser/parser.h index e1ed4c3..cf88473 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -9,10 +9,9 @@ class Parser{ private: Token *s; Lexer *lexer; - // 符号表 - Symbols *symbols;// 局部符号表 - Global *globol;// 全局符号表 - // 匹配词法单元 + stack blocks; + stack symbols; + SymbolTable top_scope; bool match(int kind){ if (s->kind == kind){ s = lexer->scan(); @@ -22,392 +21,95 @@ class Parser{ printf("%s not matched.\n", kind); return false; } - map precedence; - // 符号表管理 - Id* getId(){ - list::iterator iter; - Symbols *table = nullptr; - for (table = symbols; table != nullptr; table = table->prev){ - for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ - if ((*iter)->s->word == ((Word*)s)->word){ - return (*iter); - } - } - } - printf("[%d] %s undeclared.\n", lexer->line, ((Word*)s)->word.c_str()); - return nullptr; + void getNextToken() { + s = lexer->scan(); } + map precedence; void init_precedence() { - precedence["[]"] = 1; // level 1 - precedence["()"] = 1; - precedence["->"] = 1; - precedence["."] = 1; - - precedence["!"] = 2; // level 2 - precedence["~"] = 2; - precedence["++"] = 2; - precedence["--"] = 2; - precedence["-"] = 2; - //precedence["(T)"] = 2; - //precedence["*"] = 2; - //precedence["&"] = 2; - precedence["sizeof"] = 2; + precedence["[]"] = 13; + precedence["()"] = 13; + precedence["->"] = 12; + precedence["."] = 12; - precedence["*"] = 3; // level 3 - precedence["/"] = 3; - precedence["%"] = 3; + precedence["!"] = 12; + precedence["~"] = 12; + precedence["++"] = 12; + precedence["--"] = 12; + precedence["-"] = 12; - precedence["+"] = 4; // level 4 - precedence["-"] = 4; + precedence["sizeof"] = 11; - precedence["<<"] = 5; // level 5 - precedence[">>"] = 5; + precedence["*"] = 10; + precedence["/"] = 10; + precedence["%"] = 10; - precedence["<"] = 6; // level 6 - precedence["<="] = 6; - precedence[">="] = 6; - precedence[">"] = 6; + precedence["+"] = 9; + precedence["-"] = 9; - precedence["=="] = 7; // level 7 - precedence["!="] = 7; + precedence["<<"] = 8; + precedence[">>"] = 8; - precedence["&"] = 8; // bit logic - precedence["~"] = 3; - precedence["|"] = 10; + precedence["<"] = 7; + precedence["<="] = 7; + precedence[">="] = 7; + precedence[">"] = 7; - precedence["&&"] = 11; // logical - precedence["||"] = 12; + precedence["=="] = 6; + precedence["!="] = 6; + precedence["&"] = 5; + precedence["~"] = 4; + precedence["|"] = 3; + precedence["&&"] = 2; + precedence["||"] = 1; + } + int GetTokPrecedence() { + return precedence[((Word*)s)->word]; } bool compare(string &opa, string &opb) { return precedence[opa] > precedence[opb]; } protected: // 外部结构 - void node(){ - while (s->kind == BASIC){ - node_decl(); - } - } - void node_decl(){ - Type *type = (Type*)s; - match(BASIC); - Token *token = s; - match(ID); - if (s->kind == '('){ - // 函数体分析 - Function *f = node_func(((Word*)token)->word, type); - globol->funcs.push_back(f); - } - else{ - Id *id = new Id(type, (Word*)token); - symbols->ids.push_back(id); - globol->ids.push_back(id); - while (s->kind == ','){ - match(','); - id = new Id(type, (Word*)s); - symbols->ids.push_back(id); - globol->ids.push_back(id); - match(ID); - } - match(';'); - } - return; - } - Function* node_func(string name, Type *type){ - Function *f = new Function(name, type); - symbols->ids.push_back(new Id(type, f)); - // 符号表入栈 - f->params->prev = symbols; - symbols = f->params; - match('('); - int offset = 0; - if (s->kind == BASIC){ - Type *type = (Type*)s; - match(BASIC); - symbols->ids.push_back(new Id(type, (Word*)s)); - match(ID); - while (s->kind == ','){ - match(','); - match(BASIC); - symbols->ids.push_back(new Id(type, (Word*)s)); - match(ID); - } - } - match(')'); - f->symbols->prev = symbols; - symbols = f->symbols; - f->body = stmts(); - // 符号表出栈 - symbols = symbols->prev; - symbols = symbols->prev; - return f; - } - // 语法分析子程序 - Stmt* stmt() - { - Stmt *st = nullptr; - // 语法分析 - switch (s->kind){ - case BASIC:st = stmt_decl(); break; - case ID: - { - switch (getId()->s->kind){ - case ID:st = stmt_assign(); break; - case FUNCTION:st = expr_call(); match(';'); break; - default:printf("unknown id.\n"); break; - } - break; - } - case IF:st = stmt_if(); break; - case WHILE:st = stmt_while(); break; - case DO:st = stmt_do(); break; - case FOR:st = stmt_for(); break; - case CASE:st = stmt_case(); break; - case BREAK:st = stmt_break(); break; - case CONTINUE:st = stmt_continue(); break; - case TRY:st = stmt_try(); break; - case ';':match(';'); break; - case '{':st = stmts(); break; - default:match(s->kind); break; - } - return st; - } - Stmt* stmts(){ - Stmts *sts = new Stmts; - // 符号表入栈 - Symbols *table = new Symbols; - symbols->next = table; - table->prev = symbols; - symbols = table; - // 语法分析 - sts->line = lexer->line; - match('{'); - while (s->kind != '}'){ - Stmt *st = stmt(); - if (st)sts->Ss.push_back(st); - } - match('}'); - // 符号表出栈 - symbols = symbols->prev; - return sts; - } - // 定义 - Stmt* stmt_decl(){ - Decl *d = new Decl; - d->line = lexer->line; - Type *type = (Type*)s; - match(BASIC); - symbols->ids.push_back(new Id(type, (Word*)s)); - match(ID); - while (s->kind == ','){ - match(','); - symbols->ids.push_back(new Id(type, (Word*)s)); - match(ID); - } - match(';'); - return d; - } - // 赋值 - Stmt* stmt_assign(){ - Assign *a = new Assign; - a->line = lexer->line; - a->id = getId(); - match(ID); - match('='); - a->expr = expr_expr(); - return a; - } - // 条件语句 - Stmt* stmt_if(){ - If *i = new If; - i->line = lexer->line; - match(IF); - match('('); - i->cond = expr_cond(); - match(')'); - i->body = stmt(); - if (s->kind == ELSE){ - Else *e = new Else; - match(ELSE); - e->line = i->line; - e->C = i->cond; - e->S1 = i->body; - e->S2 = stmt(); - return e; - } - return i; - } - // 循环语句 - Stmt* stmt_while(){ - While *w = new While; - w->line = lexer->line; - match(WHILE); - match('('); - w->cond = expr_cond(); - match(')'); - Break::cur.push(w); - Continue::cur.push(w);// continue 跳转到语句开头执行 - w->body = stmt(); - Continue::cur.pop(); - Break::cur.pop(); - return w; - } - Stmt* stmt_do(){ - Do *d = new Do; - d->line = lexer->line; - match(DO); - Break::cur.push(d); - Continue::cur.push(d);// continue 跳转到语句开头执行 - d->body = stmt(); - Continue::cur.pop(); - Break::cur.pop(); - match(WHILE); - match('('); - d->cond = expr_cond(); - match(')'); - match(';'); - return d; - } - Stmt* stmt_for(){ - For *f = new For; - f->line = lexer->line; - match(FOR); - match('('); - f->S1 = stmt_assign(); - match(';'); - f->C = expr_cond(); - match(';'); - f->step = stmt_assign(); - match(')'); - Break::cur.push(f); - Continue::cur.push(f->step);// continue直接跳转到第二条赋值语句开头执行 - f->body = stmt(); - Continue::cur.pop(); - Break::cur.pop(); - return f; - } - // 分支语句 - Stmt* stmt_case(){ - Case *c = new Case; - c->line = lexer->line; - match(CASE); - c->expr = expr_expr(); - while (s->kind != END){ - Integer *i = (Integer*)s; - match(INT); - match(':'); - c->Ss[i->value] = stmt(); - } - match(END); - return c; - } - Stmt* stmt_break(){ - Break *st = new Break(); - st->line = lexer->line; - match(BREAK); - match(';'); - return st; - } - Stmt* stmt_continue(){ - Continue *st = new Continue(); - st->line = lexer->line; - match(CONTINUE); - match(';'); - return st; - } - // 异常处理 - Stmt* stmt_throw() { - match(THROW); - } - Stmt* stmt_try() { - match(TRY); - Stmt* pTry = stmt(); - match(CATCH); - Stmt* pCatch = stmt(); - match(FINALLY); - Stmt* pFinnaly = stmt(); - return new TryCatch(pTry, pCatch, pFinnaly); - } - // 表达式语句 - BinaryExpr* expr_binary() { - ExprAST* pL = expr_binary(); - while (s->kind) { - Word* w = (Word*)s; - if (compare(w->word, pL->opt)) { - ExprAST* pR = expr_binary(); - } - pL = new BinaryExpr(w->word, pL, pR); - } - return pL; - } - UnaryExpr* expr_unary() { - match('-'); - } - UnaryExpr* expr_unary(){ - Expr *u; - if (s->kind == '~'){ - match('~'); - u = new UnaryExpr("~", expr_unary()); - } - else{ - u = expr_factor(); - } - return u; - } - ExprAST* expr_factor() - { - ExprAST* e = nullptr; - switch (s->kind){ - case '(': match('('); e = expr_binary(); match(')'); break; - case ID: - { - switch (getId()->s->kind){ - case ID:e = getId(); match(ID); break; - case FUNCTION:e = expr_call(); break; - default:printf("unknown id.\n"); break; - } - break; - } - case NUM: e = new Number((Integer*)s); match(NUM); break; - default: printf("F->('%c')\n", s->kind); match(s->kind); break; - } - return e; - } - // 函数调用 - ExprAST* expr_call(){ - Call *c = new Call; - c->line = lexer->line; - c->func = (Function*)getId()->s; - match(ID); - // 函数调用 - match('('); - while (s->kind == ID || s->kind == NUM){ - ExprAST *e = expr_binary(); - if (e)c->args.push_back(e); - if (s->kind == ',') match(','); - } - match(')'); - return c; - } + void parseBlocks(); + void parseDefinition(); + PrototypeAST* parsePrototype(string name, Type *type); + FunctionAST *parseFunction(string name, Type *type); + // 语句块 + Stmt* parseStmt(); + Stmt* parseBlock(); + Stmt* parseDeclaration(); + // 控制流 + Stmt* parseIfElse(); + Stmt* parseWhileDo(); + Stmt* parseDoWhile(); + Stmt* parseFor(); + Stmt* parseSwitch(); + Stmt* parseBreak(); + Stmt* parseContinue(); + Stmt* parseThrow(); + Stmt* parseTryCatch(); + // 表达式 + ExprAST* parseExpression(); + ExprAST* parseBinaryExpr(int ExprPrec, ExprAST *lhs); + ExprAST* parsePrimary(); + ExprAST* parseIdentifierExpr(); + ExprAST* parseConstantExpr(); + ExprAST* parseBracketsExpr(); + ExprAST* parseUnaryExpr(); public: Parser(){ init_precedence(); lexer = new Lexer(); - symbols = new Symbols(); - globol = new Global(); } ~Parser(){ printf("~Parser\n"); precedence.clear(); delete lexer; - delete symbols; - delete globol; } ASTNode* parse(char *filename){ lexer->open(filename); s = lexer->scan();// 预读一个词法单元,以便启动语法分析 - node(); - return globol; + parseBlocks(); } }; From e73fd45a01c248406a8717dbaff543e566592835 Mon Sep 17 00:00:00 2001 From: mbs0221 Date: Wed, 19 Feb 2020 00:26:40 +0800 Subject: [PATCH 21/22] update project --- Parser/Parser.vcxproj | 2 + Parser/Parser.vcxproj.filters | 6 + Parser/builder.cpp | 21 ++++ Parser/builder.h | 17 +++ Parser/inter.cpp | 227 +++++++++------------------------- Parser/inter.h | 99 +++++++-------- Parser/main.cpp | 2 +- 7 files changed, 145 insertions(+), 229 deletions(-) create mode 100644 Parser/builder.cpp create mode 100644 Parser/builder.h diff --git a/Parser/Parser.vcxproj b/Parser/Parser.vcxproj index 6da8311..e369b4f 100644 --- a/Parser/Parser.vcxproj +++ b/Parser/Parser.vcxproj @@ -72,11 +72,13 @@ + + diff --git a/Parser/Parser.vcxproj.filters b/Parser/Parser.vcxproj.filters index 1632e03..123a9ff 100644 --- a/Parser/Parser.vcxproj.filters +++ b/Parser/Parser.vcxproj.filters @@ -35,6 +35,9 @@ 璧勬簮鏂囦欢 + + 澶存枃浠 + @@ -51,5 +54,8 @@ 婧愭枃浠 + + 婧愭枃浠 + \ No newline at end of file diff --git a/Parser/builder.cpp b/Parser/builder.cpp new file mode 100644 index 0000000..6d4ee13 --- /dev/null +++ b/Parser/builder.cpp @@ -0,0 +1,21 @@ +#include "builder.h" + +Value * Builder::CreateFAdd(Value * L, Value * R, string name) +{ + return nullptr; +} + +Value * Builder::CreateFSub(Value * L, Value * R, string name) +{ + return nullptr; +} + +Value * Builder::CreateFMul(Value * L, Value * R, string name) +{ + return nullptr; +} + +Value * Builder::CreateFDiv(Value * L, Value * R, string name) +{ + return nullptr; +} diff --git a/Parser/builder.h b/Parser/builder.h new file mode 100644 index 0000000..98f6dcf --- /dev/null +++ b/Parser/builder.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +using namespace std; + +class Value { + +}; + +class Builder { +public: + Value *CreateFAdd(Value *L, Value *R, string name); + Value *CreateFSub(Value *L, Value *R, string name); + Value *CreateFMul(Value *L, Value *R, string name); + Value *CreateFDiv(Value *L, Value *R, string name); +}; \ No newline at end of file diff --git a/Parser/inter.cpp b/Parser/inter.cpp index 6cae8a2..5c9d8f7 100644 --- a/Parser/inter.cpp +++ b/Parser/inter.cpp @@ -1,242 +1,127 @@ #include "inter.h" -void Stmt::Codegen(FILE * fp) +Value * Stmt::Codegen() { - ASTNode::Codegen(fp); - printf("[%04d]", line); } -void Block::Codegen(FILE * fp) +Value * Block::Codegen() { - Stmt::Codegen(fp); - //printf("stmts\n"); - //list::iterator iter; - //for (iter = Ss.begin(); iter != Ss.end(); iter++) { - // (*iter)->Codegen(fp); - //} + for (Stmt *blk : block) { + blk->Codegen(); + } } -void ExprAST::Codegen(FILE * fp) +Value * BinaryExprAST::Codegen() { - Stmt::Codegen(fp); + pL->Codegen(); + pR->Codegen(); } -void BinaryExprAST::Codegen(FILE * fp) +Value * UnaryExprAST::Codegen() { - ExprAST::Codegen(fp); - pL->Codegen(fp); - pR->Codegen(fp); + E1->Codegen(); } -void UnaryExprAST::Codegen(FILE * fp) +Value * VariableExprAST::Codegen() { - ExprAST::Codegen(fp); - E1->Codegen(fp); } -void VariableExprAST::Codegen(FILE * fp) +Value * AssignExprAST::Codegen() { - ExprAST::Codegen(fp); - /*char *width = type == Type::Int ? "dw" : "b"; - if (global) { - fprintf(fp, "\tload%s $%d %s\n", width, label, name->getName()); - } - else { - fprintf(fp, "\tload%s $%d %s\n", width, label, name->getName()); - }*/ + expr->Codegen(); } -void AssignExprAST::Codegen(FILE * fp) +Value * ConstantExprAST::Codegen() { - ExprAST::Codegen(fp); - expr->Codegen(fp); - /*if (id->global) { - fprintf(fp, "\tstore %s $%d\n", id->getName(), expr->label); - } - else { - fprintf(fp, "\tstore %s $%d\n", id->getName(), expr->label); - }*/ } -void ConstantExprAST::Codegen(FILE * fp) +Value * AccessExprAST::Codegen() +{ + return nullptr; +} + +Value * MemberExpr::Codegen() { - ExprAST::Codegen(fp); - char width = s->value > 256 ? 'w' : 'b'; - fprintf(fp, "\tload%c $%d %d\n", width, label, s->value); + return nullptr; } -void CallExprAST::Codegen(FILE * fp) +Value * CallExprAST::Codegen() { - ExprAST::Codegen(fp); - printf("call\n"); - // 参数计算 vector::iterator iter; for (ExprAST* expr : args) { - expr->Codegen(fp); + expr->Codegen(); } - // 传递参数 reverse(args.begin(), args.end()); for (ExprAST* expr : args) { - fprintf(fp, "\tparam $%d\n", expr->label); + } - // 调用语句 - fprintf(fp, "\tcall %s\n", callee); } -void Decl::Codegen(FILE * fp) +Value * Decl::Codegen() { - Stmt::Codegen(fp); - /*fprintf(fp, "\tdata\n"); - list::iterator iter; - for (iter = ids.begin(); iter != ids.end(); iter++) { - printf("\t$%s [%d]\n", (*iter)->getName(), (*iter)->getWidth()); - fprintf(fp, "\t\t$%s [%d]\n", (*iter)->getName(), (*iter)->getWidth()); - } - printf("data\n"); - fprintf(fp, "\tdata\n");*/ -} - -void IfElse::Codegen(FILE * fp) -{ - Stmt::Codegen(fp); - cond->Codegen(fp); - body_t->next = newlabel(); - fprintf(fp, "jz L%d:\n", body_t->next); - // True - body_t->Codegen(fp); - next = newlabel(); - fprintf(fp, "jmp L%d:\n", next); - fprintf(fp, "L%d:\n", body_t->next); - // False +} + +Value * IfElse::Codegen() +{ + cond->Codegen(); + body_t->Codegen(); if (body_f) { - body_f->next = newlabel(); - body_f->Codegen(fp); + body_f->Codegen(); } - fprintf(fp, "L%d:\n", next); } -void WhileDo::Codegen(FILE * fp) +Value * WhileDo::Codegen() { - Stmt::Codegen(fp); - begin = newlabel(); - next = newlabel(); - body->next = begin; - fprintf(fp, "L%d:\n", begin); - cond->Codegen(fp); - fprintf(fp, "jz L:\n", next);// False跳转 - body->Codegen(fp); - fprintf(fp, "\tjmp L%d\n", begin); - fprintf(fp, "L%d:\n", next); + cond->Codegen(); + body->Codegen(); } -void DoWhile::Codegen(FILE * fp) +Value * DoWhile::Codegen() { - Stmt::Codegen(fp); - begin = newlabel(); - body->next = begin; - fprintf(fp, "L%d:\n", begin); - body->Codegen(fp); - cond->Codegen(fp); - fprintf(fp, "jnz L%d:\n", begin);// True跳转 + body->Codegen(); + cond->Codegen(); } -void For::Codegen(FILE * fp) +Value * For::Codegen() { - Stmt::Codegen(fp); - begin = newlabel(); - next = newlabel(); - step->begin = newlabel(); - step->next = newlabel(); - body->next = begin; - init->Codegen(fp); - fprintf(fp, "L%d:\n", begin); - cond->Codegen(fp); - fprintf(fp, "L%d:\n", cond->label); // False跳转 - body->Codegen(fp); - fprintf(fp, "L%d:\n", step->begin); - step->Codegen(fp); - fprintf(fp, "\tjmp L%d\n", begin); - fprintf(fp, "L%d:\n", next); + init->Codegen(); + cond->Codegen(); + body->Codegen(); + step->Codegen(); } -void Switch::Codegen(FILE * fp) +Value * Switch::Codegen() { - Stmt::Codegen(fp); - expr->Codegen(fp); + expr->Codegen(); for (Case cs : cases) { - fprintf(fp, "= $%d $%d\n", expr->label, cs.first); - fprintf(fp, "jne L%d", cs.second->begin); - cs.second->Codegen(fp); - fprintf(fp, "L%d", cs.second->next); + cs.second->Codegen(); } } -void Break::Codegen(FILE * fp) +Value * Break::Codegen() { - Stmt::Codegen(fp); - fprintf(fp, "\tjmp L%d\n", stmt->next); } -void Continue::Codegen(FILE * fp) +Value * Continue::Codegen() { - Stmt::Codegen(fp); - fprintf(fp, "\tjmp L%d\n", next->begin); } -void Throw::Codegen(FILE * fp) +Value * Throw::Codegen() { - Stmt::Codegen(fp); - fprintf(fp, "\tjmp L%d\n", exception->kind); } -void TryCatch::Codegen(FILE * fp) +Value * TryCatch::Codegen() { - Stmt::Codegen(fp); - // 需要异常处理的程序 - pTry->Codegen(fp); - fprintf(fp, "\tjmp L%d\n", pCatch->next); - // 异常处理程序 - fprintf(fp, "L%d:\n", pCatch->begin); - pCatch->Codegen(fp); - fprintf(fp, "L%d:\n", pCatch->next); - // 扫尾操作 - pFinally->Codegen(fp); + pTry->Codegen(); + pCatch->Codegen(); + pFinally->Codegen(); } -void FunctionAST::Codegen(FILE * fp) +Value * FunctionAST::Codegen() { - //fprintf(fp, "proc %s:\n", word.c_str()); - //list::iterator iter; - //int width = type->width; - //for (iter = params->ids.begin(); iter != params->ids.end(); iter++){ - // (*iter)->offset = width; - // (*iter)->global = false; - // fprintf(fp, "\t;%s @%d\n", (*iter)->getName(), width); - // width += (*iter)->getWidth(); - //} - //width = 0; - //Symbols *table = symbols; - //for (table = symbols; table != nullptr; table = table->next){ - // for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ - // (*iter)->offset = width; - // (*iter)->global = false; - // fprintf(fp, "\t;%s @%d\n", (*iter)->getName(), width); - // width += (*iter)->getWidth(); - // } - //} - //fprintf(fp, "\tsub $sp %d\n", width); - //width = 0; - //for (table = params; table != nullptr; table = table->next){ - // for (iter = table->ids.begin(); iter != table->ids.end(); iter++){ - // (*iter)->offset = width; - // (*iter)->global = false; - // width += (*iter)->getWidth(); - // } - //} - //body->code(fp); - //fprintf(fp, "endp\n"); } -void PrototypeAST::Codegen(FILE * fp) +Value * PrototypeAST::Codegen() { } + diff --git a/Parser/inter.h b/Parser/inter.h index accd641..3991b7b 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -5,13 +5,14 @@ #include #include +#include "builder.h" class Visitor; class ASTNode{ friend class Visitor; public: - virtual void Codegen(FILE *fp) = 0; + virtual Value * Codegen() = 0; }; //语句 @@ -23,7 +24,7 @@ class Stmt : ASTNode{ static int newlabel(){ return label++; } - virtual void Codegen(FILE *fp); + virtual Value * Codegen() = 0; }; int Stmt::label = 0; @@ -33,7 +34,7 @@ class Block : public Stmt{ vector block; public: Block(vector &block) : block(block) { } - virtual void Codegen(FILE *fp); + Value * Codegen(); }; //表达式 @@ -43,7 +44,7 @@ class ExprAST : public Stmt{ int label; static int count; ExprAST() { label = count++; } - virtual void Codegen(FILE *fp); + virtual Value * Codegen() = 0; }; int ExprAST::count = 0; @@ -54,7 +55,7 @@ class BinaryExprAST : public ExprAST { public: BinaryExprAST(int opt, ExprAST *pL, ExprAST *pR) : opt(opt), pL(pL), pR(pR) { } - virtual void Codegen(FILE *fp); + Value * Codegen(); }; class UnaryExprAST : public ExprAST{ @@ -63,14 +64,14 @@ class UnaryExprAST : public ExprAST{ public: UnaryExprAST(int opt, ExprAST *E1) : opt(opt), E1(E1){ } - virtual void Codegen(FILE *fp); + Value * Codegen(); }; class VariableExprAST : public ExprAST { string name; public: VariableExprAST(const string &name) : name(name){ } - void Codegen(FILE *fp); + Value * Codegen(); }; class AssignExprAST : public VariableExprAST { @@ -78,14 +79,14 @@ class AssignExprAST : public VariableExprAST { public: AssignExprAST(const string &name, ExprAST *expr) : VariableExprAST(name), expr(expr) { } - void Codegen(FILE *fp); + Value * Codegen(); }; class ConstantExprAST : public ExprAST { Integer *s; public: ConstantExprAST(Integer *s) : s(s) { } - void Codegen(FILE *fp); + Value * Codegen(); }; class AccessExprAST : public VariableExprAST { @@ -93,23 +94,25 @@ class AccessExprAST : public VariableExprAST { public: AccessExprAST(const string &name, ExprAST *loc) : VariableExprAST(name), loc(loc) { } + Value * Codegen(); }; -//class MemberExpr : public ExprAST { -// string name; -// ExprAST *index; -//public: -// MemberExpr(const string name, ExprAST *index) -// : name(name), index(index) { } -//}; -// -//class PointerExpr : public ExprAST { -// string name; -// ExprAST *index; -//public: -// PointerExpr(const string name, ExprAST *index) -// : name(name), index(index) { } -//}; +class MemberExpr : public ExprAST { + string name; + ExprAST *index; +public: + MemberExpr(const string name, ExprAST *index) + : name(name), index(index) { } + Value * Codegen(); +}; + +class PointerExpr : public ExprAST { + string name; + ExprAST *index; +public: + PointerExpr(const string name, ExprAST *index) + : name(name), index(index) { } +}; class CallExprAST : public ExprAST { string callee; @@ -118,13 +121,13 @@ class CallExprAST : public ExprAST { CallExprAST() { args.clear(); } CallExprAST(const string &callee, vector &args) : callee(callee), args(args) { ; } - void Codegen(FILE *fp); + Value * Codegen(); }; class Decl : Stmt{ list ids; public: - void Codegen(FILE *fp); + Value * Codegen(); }; class IfElse : public Stmt{ @@ -134,7 +137,7 @@ class IfElse : public Stmt{ public: IfElse(ExprAST *cond, Stmt *body_t, Stmt *body_f) : cond(cond), body_t(body_t), body_f(body_f) { } - void Codegen(FILE *fp); + Value * Codegen(); }; class WhileDo : public Stmt{ @@ -142,7 +145,7 @@ class WhileDo : public Stmt{ Stmt *body; public: WhileDo(ExprAST *cond, Stmt *body) :cond(cond), body(body) { } - void Codegen(FILE *fp); + Value * Codegen(); }; class DoWhile : public Stmt{ @@ -150,7 +153,7 @@ class DoWhile : public Stmt{ Stmt *body; public: DoWhile(ExprAST *cond, Stmt *body) :cond(cond), body(body) { } - void Codegen(FILE *fp); + Value * Codegen(); }; class For : public Stmt{ @@ -159,7 +162,7 @@ class For : public Stmt{ public: For(ExprAST *init, ExprAST *cond, ExprAST *step, Stmt *body) : init(init), cond(cond), step(step), body(body) { } - void Codegen(FILE *fp); + Value * Codegen(); }; typedef pair Case; @@ -170,21 +173,21 @@ class Switch : public Stmt { public: Switch(ExprAST *expr, vector> &cases) : expr(expr), cases(cases) { } - void Codegen(FILE *fp); + Value * Codegen(); }; class Break : public Stmt{ Stmt *stmt; public: Break(Stmt *next) : stmt(next) { } - void Codegen(FILE *fp); + Value * Codegen(); }; class Continue : public Stmt{ Stmt *next; public: Continue(Stmt *next) : next(next) { } - void Codegen(FILE *fp); + Value * Codegen(); }; class Throw : public Stmt { @@ -193,7 +196,7 @@ class Throw : public Stmt { Throw() { exception = nullptr; } - void Codegen(FILE *fp); + Value * Codegen(); }; class TryCatch : public Stmt{ @@ -201,29 +204,11 @@ class TryCatch : public Stmt{ public: TryCatch(Stmt* pTry, Stmt* pCatch, Stmt* pFinally) : pTry(pTry), pCatch(pCatch), pFinally(pFinally) { } - void Codegen(FILE *fp); + Value * Codegen(); }; -// -------------符号表----------- typedef map SymbolTable; -//class Symbols{ -//public: -// int id; -// static int count; -// list ids; -// Symbols *prev, *next; -// Symbols(){ -// id = count++; -// ids.clear(); -// prev = nullptr; -// next = nullptr; -// } -//}; -// -//int Symbols::count = 0; - -// -------------函数----------- class ParameterAST { Type *type; string name; @@ -238,7 +223,7 @@ class PrototypeAST { public: PrototypeAST(Type *type, const string &name, vector &args) : type(type), name(name), args(args) { } - void Codegen(FILE * fp); + Value * Codegen(); }; class FunctionAST { @@ -246,19 +231,19 @@ class FunctionAST { Stmt *body; public: FunctionAST(PrototypeAST *proto, Stmt *body) : proto(proto), body(body) { } - void Codegen(FILE * fp); + Value * Codegen(); }; class Global : ASTNode { map symbols; public: - void putId(string name, Type* type) { + Value * putId(string name, Type* type) { symbols[name] = type; } Type* getId(string name) { return symbols[name]; } - virtual void code(FILE *fp){ + Value * code(){ ASTNode::Codegen(fp); } }; diff --git a/Parser/main.cpp b/Parser/main.cpp index f4464b4..e58f201 100644 --- a/Parser/main.cpp +++ b/Parser/main.cpp @@ -11,7 +11,7 @@ void main(){ printf("编译开始\n"); printf(" line stmt\n"); fopen_s(&fp, "data.s", "w"); - st->Codegen(fp); + st->Codegen(); fclose(fp); printf("编译结束\n"); delete p; From 48eab0403061fad8cc81a65a313e985b272cc545 Mon Sep 17 00:00:00 2001 From: mbs0221 Date: Wed, 19 Feb 2020 13:16:45 +0800 Subject: [PATCH 22/22] update project --- Asm/asm.h | 12 ++--- Asm/lexer.h | 12 ++--- Parser/inter.cpp | 12 +++-- Parser/inter.h | 50 +++++++++--------- Parser/lexer.h | 22 ++++---- Parser/main.cpp | 2 +- Parser/parser.cpp | 127 ++++++++++++++++++++++++++++------------------ Parser/parser.h | 12 ++--- 8 files changed, 139 insertions(+), 110 deletions(-) diff --git a/Asm/asm.h b/Asm/asm.h index 08cbf76..3d3964f 100644 --- a/Asm/asm.h +++ b/Asm/asm.h @@ -137,8 +137,8 @@ class Asm{ match(':'); Code *body = match_codes(); match(ENDP); - Proc *proc = new Proc(lexer->line, w->word, body); - funcs[w->word] = proc; + Proc *proc = new Proc(lexer->line, w->str, body); + funcs[w->str] = proc; return proc; } Code* match_codes() { @@ -179,13 +179,13 @@ class Asm{ Code* match_label() { Word *w = match_word(); match(':'); - return add_label(w->word); + return add_label(w->str); } Code* match_call(){ match(CALL); Word *w = match_word(); - if (funcs.find(w->word) != funcs.end()){ - Proc *func = funcs[w->word]; + if (funcs.find(w->str) != funcs.end()){ + Proc *func = funcs[w->str]; match(ID); return new Call(lexer->line, func); } @@ -231,7 +231,7 @@ class Asm{ Code* match_jmp(){ match(JMP); Word *w = match_word(); - Label *label = (Label*)add_label(w->word); + Label *label = (Label*)add_label(w->str); match(ID); return new Jmp(lexer->line, label); } diff --git a/Asm/lexer.h b/Asm/lexer.h index 3b06179..477a015 100644 --- a/Asm/lexer.h +++ b/Asm/lexer.h @@ -31,12 +31,12 @@ struct Token{ }; struct Word :Token{ - string word; - Word(int tag, string word) :Token(tag), word(word) { } + string str; + Word(int tag, string str) :Token(tag), str(str) { } virtual string place(){ - ostringstream s; - s << word; - return s.str(); + ostringstream os; + os << str; + return os.str(); } virtual string code(){ return ""; @@ -49,7 +49,7 @@ struct Type :Word{ Type(int kind, string word, int width) :Word(kind, word), width(width){ } virtual string place(){ ostringstream s; - s << word << ":" << width; + s << str << ":" << width; return s.str(); } virtual string code(){ diff --git a/Parser/inter.cpp b/Parser/inter.cpp index 5c9d8f7..5ef906e 100644 --- a/Parser/inter.cpp +++ b/Parser/inter.cpp @@ -13,13 +13,13 @@ Value * Block::Codegen() Value * BinaryExprAST::Codegen() { - pL->Codegen(); - pR->Codegen(); + lhs->Codegen(); + rhs->Codegen(); } Value * UnaryExprAST::Codegen() { - E1->Codegen(); + rhs->Codegen(); } Value * VariableExprAST::Codegen() @@ -28,7 +28,7 @@ Value * VariableExprAST::Codegen() Value * AssignExprAST::Codegen() { - expr->Codegen(); + rhs->Codegen(); } Value * ConstantExprAST::Codegen() @@ -125,3 +125,7 @@ Value * PrototypeAST::Codegen() { } +Value * ParameterAST::Codegen() +{ + return nullptr; +} diff --git a/Parser/inter.h b/Parser/inter.h index 3991b7b..e256149 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -9,14 +9,14 @@ class Visitor; -class ASTNode{ +class AST{ friend class Visitor; public: virtual Value * Codegen() = 0; }; -//语句 -class Stmt : ASTNode{ +// 语句 +class Stmt : public AST{ public: int line; int begin, next; @@ -29,7 +29,7 @@ class Stmt : ASTNode{ int Stmt::label = 0; -//语句块 +// 语句块 class Block : public Stmt{ vector block; public: @@ -41,51 +41,47 @@ class Block : public Stmt{ class ExprAST : public Stmt{ public: Type *type; - int label; - static int count; - ExprAST() { label = count++; } virtual Value * Codegen() = 0; }; -int ExprAST::count = 0; - class BinaryExprAST : public ExprAST { int opt; - ExprAST *pL, *pR; + ExprAST *lhs, *rhs; public: BinaryExprAST(int opt, ExprAST *pL, ExprAST *pR) - : opt(opt), pL(pL), pR(pR) { } + : opt(opt), lhs(pL), rhs(pR) { } Value * Codegen(); }; class UnaryExprAST : public ExprAST{ int opt; - ExprAST *E1; + ExprAST *rhs; public: UnaryExprAST(int opt, ExprAST *E1) - : opt(opt), E1(E1){ } + : opt(opt), rhs(E1){ } Value * Codegen(); }; class VariableExprAST : public ExprAST { string name; + Type *type; public: - VariableExprAST(const string &name) : name(name){ } + VariableExprAST(const string &name, Type *type) : name(name), type(type){ } Value * Codegen(); }; class AssignExprAST : public VariableExprAST { - ExprAST *expr; + ExprAST *rhs; public: - AssignExprAST(const string &name, ExprAST *expr) - : VariableExprAST(name), expr(expr) { } + AssignExprAST(const string &name, ExprAST *rhs) + : VariableExprAST(name), rhs(rhs) { } Value * Codegen(); }; class ConstantExprAST : public ExprAST { - Integer *s; + Integer *num; public: - ConstantExprAST(Integer *s) : s(s) { } + ConstantExprAST(Integer *num) : num(num) { } Value * Codegen(); }; @@ -130,6 +126,7 @@ class Decl : Stmt{ Value * Codegen(); }; +// 控制流 class IfElse : public Stmt{ ExprAST *cond; Stmt *body_t; @@ -207,16 +204,18 @@ class TryCatch : public Stmt{ Value * Codegen(); }; -typedef map SymbolTable; +// 环境 +typedef map SymbolTable; -class ParameterAST { +class ParameterAST : public AST{ Type *type; string name; public: ParameterAST(Type *type, string name) : type(type), name(name) { } + Value * Codegen(); }; -class PrototypeAST { +class PrototypeAST : public AST{ Type *type; string name; vector args; @@ -226,7 +225,7 @@ class PrototypeAST { Value * Codegen(); }; -class FunctionAST { +class FunctionAST : public AST{ PrototypeAST *proto; Stmt *body; public: @@ -234,7 +233,7 @@ class FunctionAST { Value * Codegen(); }; -class Global : ASTNode { +class Global { map symbols; public: Value * putId(string name, Type* type) { @@ -243,9 +242,6 @@ class Global : ASTNode { Type* getId(string name) { return symbols[name]; } - Value * code(){ - ASTNode::Codegen(fp); - } }; #endif // !__INTER_H_ diff --git a/Parser/lexer.h b/Parser/lexer.h index 698f3fa..dc79ed8 100644 --- a/Parser/lexer.h +++ b/Parser/lexer.h @@ -42,34 +42,36 @@ struct Token{ }; struct Word :Token{ - string word; - Word(int tag, string word) :Token(tag), word(word) { } + string str; + Word(int tag, string word) :Token(tag), str(word) { } virtual string place(){ ostringstream s; - s << word; + s << str; return s.str(); } virtual string code(){ - return word; + return str; } - const char* getName() { return word.c_str(); } + const char* getName() { return str.c_str(); } }; struct Type :Word{ int width; - static Type *Int, *Char, *Void; + static Type *Int, *Float, *Double, *Char, *Void; Type(int kind, string word, int width) :Word(kind, word), width(width){ } virtual string place(){ ostringstream s; - s << word << ":" << width; + s << str << ":" << width; return s.str(); } virtual string code(){ - return word; + return str; } }; -Type* Type::Int = new Type(BASIC, "dw", 4); +Type* Type::Int = new Type(BASIC, "qw", 4); +Type* Type::Float = new Type(BASIC, "dw", 2); +Type* Type::Double = new Type(BASIC, "qw", 4); Type* Type::Char = new Type(BASIC, "db", 1); Type* Type::Void = new Type(BASIC, "void", 0); @@ -143,6 +145,8 @@ class Lexer{ Lexer(){ words["int"] = Type::Int; words["char"] = Type::Char; + words["float"] = Type::Float; + words["double"] = Type::Double; words["void"] = Type::Void; words["if"] = new Word(IF, "if"); words["then"] = new Word(THEN, "then"); diff --git a/Parser/main.cpp b/Parser/main.cpp index e58f201..ca0af8d 100644 --- a/Parser/main.cpp +++ b/Parser/main.cpp @@ -6,7 +6,7 @@ void main(){ FILE *fp = &file; Parser *p = new Parser(); printf("开始语法分析\n"); - ASTNode *st = p->parse("Text.txt"); + AST *st = p->parse("Text.txt"); printf("语法分析结束\n"); printf("编译开始\n"); printf(" line stmt\n"); diff --git a/Parser/parser.cpp b/Parser/parser.cpp index 453f14b..7c1e419 100644 --- a/Parser/parser.cpp +++ b/Parser/parser.cpp @@ -14,16 +14,16 @@ void Parser::parseDefinition() Word *word = (Word*)s; match(ID); if (word->kind != '(') { - top_scope[word->word] = type; + global[word->str] = new VariableExprAST(word->str, type); while (s->kind == ',') { match(','); - top_scope[word->word] = type; + global[word->str] = new VariableExprAST(word->str, type); match(ID); } match(';'); return; } - FunctionAST *f = parseFunction(word->word, type); + global[word->str] = parseFunction(word->str, type); } PrototypeAST * Parser::parsePrototype(string name, Type * type) @@ -34,12 +34,12 @@ PrototypeAST * Parser::parsePrototype(string name, Type * type) if (s->kind == BASIC) { Type *type = (Type*)s; match(BASIC); - args.push_back(new ParameterAST(type, ((Word*)s)->word)); + args.push_back(new ParameterAST(type, ((Word*)s)->str)); match(ID); while (s->kind == ',') { match(','); match(BASIC); - args.push_back(new ParameterAST(type, ((Word*)s)->word)); + args.push_back(new ParameterAST(type, ((Word*)s)->str)); match(ID); } } @@ -59,26 +59,49 @@ FunctionAST * Parser::parseFunction(string name, Type * type) return 0; } +FunctionAST * Parser::parseTopLevelExpr() +{ + if (Stmt *Body = parseStmt()) { + // Make and anonymous proto + PrototypeAST *Proto = new PrototypeAST(Type::Void, "main", std::vector()); + return new FunctionAST(Proto, Body); + } + return 0; +} + Stmt * Parser::parseStmt() { - Stmt *st = nullptr; // 语法分析 switch (s->kind) { - case BASIC:st = parseDeclaration(); break; - case ID:parseExpression(); break; - case IF:st = parseIfElse(); break; - case WHILE:st = parseWhileDo(); break; - case DO:st = parseDoWhile(); break; - case FOR:st = parseFor(); break; - case CASE:st = parseSwitch(); break; - case BREAK:st = parseBreak(); break; - case CONTINUE:st = parseContinue(); break; - case TRY:st = parseTryCatch(); break; - case ';':match(';'); break; - case '{':st = parseBlock(); break; - default:match(s->kind); break; + case BASIC: + return parseDeclaration(); + case ID: + return parseExpression(); + case IF: + return parseIfElse(); + case WHILE: + return parseWhileDo(); + case DO: + return parseDoWhile(); + case FOR: + return parseFor(); + case CASE: + return parseSwitch(); + case BREAK: + return parseBreak(); + case CONTINUE: + return parseContinue(); + case TRY: + return parseTryCatch(); + case ';': + match(';'); + return parseStmt(); + case '{': + return parseBlock(); + default: + match(s->kind); + return parseStmt(); } - return st; } Stmt * Parser::parseBlock() @@ -99,11 +122,11 @@ Stmt * Parser::parseDeclaration() { Type *type = (Type*)s; match(BASIC); - top_scope[((Word*)s)->word] = type; + top_scope[((Word*)s)->str] = type; match(ID); while (s->kind == ',') { match(','); - top_scope[((Word*)s)->word] = type; + top_scope[((Word*)s)->str] = type; match(ID); } match(';'); @@ -271,37 +294,41 @@ ExprAST * Parser::parsePrimary() ExprAST * Parser::parseIdentifierExpr() { // id ::= id | assign | call - string name = ((Word*)s)->word; - match(ID); - // assign - if (s->kind == '=') { - match('='); - ExprAST *expr = parseExpression(); - return new AssignExprAST(name, expr); - } - // call - if (s->kind == '(') { - match('('); - vector args; - if (s->kind != ')') { - while (true) { - ExprAST *arg = parseExpression(); - if (arg == nullptr) - return 0; - args.push_back(arg); - - if (s->kind == ')') - break; - - if (s->kind != ',') - return 0; - match(','); + Word *w = (Word*)s; + string id = w->str; + if (global.find(id) != global.end()) { + match(ID); + // assign + if (s->kind == '=') { + match('='); + ExprAST *expr = parseExpression(); + return new AssignExprAST(id, expr); + } + // call + if (s->kind == '(') { + match('('); + vector args; + if (s->kind != ')') { + while (true) { + ExprAST *arg = parseExpression(); + if (arg == nullptr) + return 0; + args.push_back(arg); + + if (s->kind == ')') + break; + + if (s->kind != ',') + return 0; + match(','); + } + match(')'); + return new CallExprAST(id, args); } - match(')'); - return new CallExprAST(name, args); } + return (VariableExprAST*)(global[id]); } - return new VariableExprAST(name); + return nullptr; } ExprAST * Parser::parseConstantExpr() diff --git a/Parser/parser.h b/Parser/parser.h index cf88473..e038364 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -11,7 +11,7 @@ class Parser{ Lexer *lexer; stack blocks; stack symbols; - SymbolTable top_scope; + SymbolTable top_scope, global; bool match(int kind){ if (s->kind == kind){ s = lexer->scan(); @@ -63,7 +63,7 @@ class Parser{ precedence["||"] = 1; } int GetTokPrecedence() { - return precedence[((Word*)s)->word]; + return precedence[((Word*)s)->str]; } bool compare(string &opa, string &opb) { return precedence[opa] > precedence[opb]; @@ -73,12 +73,11 @@ class Parser{ void parseBlocks(); void parseDefinition(); PrototypeAST* parsePrototype(string name, Type *type); - FunctionAST *parseFunction(string name, Type *type); - // 语句块 + FunctionAST* parseFunction(string name, Type *type); + FunctionAST *parseTopLevelExpr(); Stmt* parseStmt(); Stmt* parseBlock(); Stmt* parseDeclaration(); - // 控制流 Stmt* parseIfElse(); Stmt* parseWhileDo(); Stmt* parseDoWhile(); @@ -88,7 +87,6 @@ class Parser{ Stmt* parseContinue(); Stmt* parseThrow(); Stmt* parseTryCatch(); - // 表达式 ExprAST* parseExpression(); ExprAST* parseBinaryExpr(int ExprPrec, ExprAST *lhs); ExprAST* parsePrimary(); @@ -106,7 +104,7 @@ class Parser{ precedence.clear(); delete lexer; } - ASTNode* parse(char *filename){ + AST* parse(char *filename){ lexer->open(filename); s = lexer->scan();// 预读一个词法单元,以便启动语法分析 parseBlocks();