//"表达式"语法分析 bool KH::GrammarPL0::ExpressionParsing()//nIndentNum是打印时要缩进的空格数 { bool result = true; if( GetWord(false).GetSign() == KH::_PLUS || GetWord(false).GetSign() == KH::_MINUS) {//如果开头有正负号,则此时表达式应被看作一个正的或负的项 //Gen +- GenPush(GetWord(false).GetValue()); skip(1); } if( TermParsing() )//表达式可以是一个"项" { while( GetWord(false).GetSign() == KH::_PLUS || GetWord(false).GetSign() == KH::_MINUS) { //Gen +- GenPush(GetWord(false).GetValue()); skip(1); if( !TermParsing() ){ Error( result," Expression Parsing Error , There should be a Term ." ); } } } else { Error( result," Expression Parsing Error , There should be a Term ."); } return result; }
//条件 bool KH::GrammarPL0::ConditionParsing()//nIndentNum是打印时要缩进的空格数 { bool result = true; if( GetWord(false).GetSign() == KH::_ODD)//如果有"odd"单词 { //Gen if ( GenPush("( "); //注意闭合! skip(1); if(! ExpressionParsing()) { Error( result," Condition Parsing Error , There should be a Expression ."); } //Gen if .. ) GenPush(" ) "); //注意闭合! } else { //Gen if ( GenPush(" ( "); //注意闭合! if(! ExpressionParsing()) { Error( result," Condition Parsing Error , There should be a Expression ."); } if( GetWord(false).GetSign() == KH::_EQUAL //如果后面有逻辑运算符 || GetWord(false).GetSign() == KH::_NEQUAL || GetWord(false).GetSign() == KH::_LANGLE || GetWord(false).GetSign() == KH::_LEQUAL || GetWord(false).GetSign() == KH::_RANGLE || GetWord(false).GetSign() == KH::_REQUAL) { //Gen if ( == ) GenPush(GetWord(false).GetValue()); //注意闭合! skip(1); if(! ExpressionParsing()) { Error( result," Condition Parsing Error , There should be a Expression ."); } } else { Error( result," Condition Parsing Error , Logic Error : " + GetWord(false).GetValue()); } //Gen if .. ) GenPush(" ) "); //注意闭合! } return result; }
//"因子"语法分析 bool KH::GrammarPL0::FactorParsing() { bool result = true; switch( GetWord(false).GetSign()) { case KH::_IDENTIFIER://因子可以是一个常量或变量 Sa.ExistVariable(GetLine(),GetWord(false).GetValue()); //Gen ident GenPush(GetWord(false).GetValue()); skip(1); break; case KH::_INT: //因子可以是一个数 case KH::_FLOAT: //Gen ident GenPush(GetWord(false).GetValue()); skip(1); break; case KH::_LPAREN : //如果看到左括号'(' //Gen ( GenPush(" ( "); skip(1); if(!ExpressionParsing()) { Error( result," Factor Error , There should be a Expression ."); } if( GetWord(false).GetSign() == KH::_RPAREN)//"表达式"后面应是右括号')' { //Gen ) GenPush(" ) "); skip(1); } else{ Error( result," Factor Error , There should be a Right Paren : " + GetWord(false).GetValue()); } break; default: Error( result," Factor Error , There should be a Factor ."); break; }//End of switch return result; }
void CodeGenerator::GenNegate() { GenBlockHeader( "Negate" ); GenPop( "eax" ); GenLine( "neg eax" ); GenPush( "eax" ); }
void CodeGenerator::GenAssign( std::string addrTo ) { GenBlockHeader( "Assignment" ); GenPop( "eax" ); GenMov( addrTo, "eax" ); GenPush( "eax" ); }
void CodeGenerator::GenFuncCall( std::string funcName, int paramCountCall ) { GenReverseStack( paramCountCall ); GenBlockHeader( "Call " + funcName + " Function" ); GenLine( "CALL _" + funcName ); GenLine( "add esp, " + toString( 4 * paramCountCall ) + "d" ); GenPush( "eax" ); }
void CodeGenerator::GenMultiplication() { GenBlockHeader( "Multiply" ); GenPop( "ecx" ); GenPop( "eax" ); GenLine( "imul ecx" ); GenPush( "eax" ); }
void CodeGenerator::GenStringPush( std::string str ) { std::string strVar = "S" + toString( mStrCount++ ); GenLine( ".data" ); GenLine( strVar + " BYTE \"" + str + "\", 00h" ); GenLine( ".code" ); GenPush( "OFFSET " + strVar ); }
// GenBinaryOperation void CodeGenerator::GenBinaryOperation( std::string operationName ) { GenBlockHeader( operationName ); GenPop( "ecx" ); GenPop( "eax" ); GenLine( operationName + " eax, ecx" ); GenPush( "eax" ); }
void CodeGenerator::GenDivision() { GenBlockHeader( "Divide" ); GenPop( "ecx" ); GenPop( "eax" ); GenLine( "CDQ" ); GenLine( "idiv ecx" ); GenPush( "eax" ); }
int CodeGenerator::GenFuncStart( std::string funcName ) { GenBlockHeader( "Function " + funcName + " Declaration" ); funcName = '_' + funcName; GenLine( "PUBLIC " + funcName ); GenLine( funcName + " PROC" ); GenPush( "ebp" ); GenMov( "ebp","esp" ); GenLine(); return CreateLabel(); }
void CodeGenerator::GenNot() { GenBlockHeader( "Not" ); GenPop( "eax" ); GenMov( "edx", "0" ); GenLine( "cmp eax, 0" ); GenLine( "JNE L" + toString( ++mLabelCount ) ); GenLine( "inc edx" ); GenLabel( mLabelCount ); GenPush( "edx" ); }
void CodeGenerator::GenOr() { GenBlockHeader( "Or" ); GenPop( "ecx" ); GenPop( "eax" ); GenMov( "edx", "0" ); GenLine( "or eax, ecx" ); GenLine( "cmp eax, 0" ); GenLine( "JE L" + toString( ++mLabelCount ) ); GenLine( "inc edx" ); GenLabel( mLabelCount ); GenPush( "edx" ); }
void CodeGenerator::GenAnd() { GenBlockHeader( "And" ); GenPop( "ecx" ); GenPop( "eax" ); GenLine( "imul ecx" ); GenMov( "edx", "0" ); GenLine( "cmp eax, 0" ); mAsmCode += "JE"; mAsmCode += " L" + toString( ++mLabelCount ) + "\n"; GenLine( "inc edx" ); GenLabel( mLabelCount ); GenPush( "edx" ); }
void CodeGenerator::GenCompare( std::string sign ) { GenBlockHeader( "Compare" ); GenPop( "ecx" ); GenPop( "eax" ); GenMov( "edx", "0" ); GenLine( "cmp eax, ecx" ); if( sign == "==" ) mAsmCode += "JNE "; if( sign == "!=" ) mAsmCode += "JE"; if( sign == ">" ) mAsmCode += "JLE"; if( sign == "<" ) mAsmCode += "JGE"; if( sign == ">=" ) mAsmCode += "JL"; if( sign == "<=" ) mAsmCode += "JG"; mAsmCode += " L" + toString( ++mLabelCount ) + "\n"; GenLine( "inc edx" ); GenLabel( mLabelCount ); GenPush( "edx" ); }
//"项"语法分析 bool KH::GrammarPL0::TermParsing()//nIndentNum是打印时要缩进的空格数 { bool result = true; if(! FactorParsing()){ Error( result," Term Parsing Error , There should be a Factor ."); } while( GetWord(false).GetSign() == KH::_TIMES || GetWord(false).GetSign() == KH::_SLASH) {//如果"因子"后面还有单词'*'或'/' //Gen */ GenPush(GetWord(false).GetValue()); skip(1); if(!FactorParsing()){ Error( result," Term Parsing Error , There should be a Factor ."); } } return result; }
void CodeGenerator::GenReverseStack( int depth ) { if( depth < 2 ) return; GenBlockHeader( "Reversing last " + toString( depth ) + " stack items" ); GenLine( ".data" ); // allocate enough memory for( int i = 1; i <= depth; ++i ) { GenLine( "stackReveseVar" + toString( mStackReverseCount++ ) + " DWORD ?" ); } GenLine( ".code" ); // pop into memory for( int i = depth; i >= 1; --i ) { GenPop( "stackReveseVar" + toString( mStackReverseCount - i ) ); } for( int i = depth; i >= 1; --i ) { GenPush( "stackReveseVar" + toString( mStackReverseCount - i ) ); } }
bool KH::GrammarPL0::StatementParsing(){ bool result = true; switch( GetWord(false).GetSign()){ case KH::_IDENTIFIER: //Identifire Sa.ExistVariable(GetLine(),GetWord(false).GetValue()); //Gen a = .. GenPush(GetWord(false).GetValue() + " = ");//注意闭合 skip(1); if( GetWord(0,false).GetSign() == KH::_ASSIGN){ //Gen ) skip(1); if(!ExpressionParsing()) Error( result," Statement Error , There should be a Expression ."); } else{ Error( result," Statement Error , Assign required : " + GetWord(false).GetValue()); } //Gen a = .. ; GenPush(" ; ");//注意闭合 break; case KH::_CALL: //Call skip(1); if( GetWord(0,false).GetSign() == KH::_IDENTIFIER){ Sa.ExistVariable(GetLine(),GetWord(false).GetValue()); //Gen a(); GenPush(GetWord(false).GetValue() + " () ;"); skip(1); } else{ Error( result," Statement Error , Identifier required : " + GetWord(false).GetValue()); } break; case KH::_LBIGPAREN: //Begin case KH::_BEGIN: skip(1); //Gen { GenPush(" { ");//注意闭合 if(Block()){ while( GetWord(0,false).GetSign() == KH::_SEMICOLON){ //Gen ; GenPush(";"); skip(1); if(GetWord(0,false).GetSign() == KH::_END || GetWord(0,false).GetSign() == KH::_RBIGPAREN) { break; } if(!StatementParsing()) Error( result," Statement Error , Statement required ."); } if( GetWord(0,false).GetSign() == KH::_RBIGPAREN || GetWord(0,false).GetSign() == KH::_END) { //Gen } GenPush(" } ");//注意闭合 skip(1); } else Error( result," Statement Error , 'end' or '}' required : " + GetWord(false).GetValue() ); } else{ Error( result," Statement Error , Statement required ."); } break; case KH::_IF: //Gen if GenPush(" if "); skip(1); if( ConditionParsing()){ //skip(1); if( GetWord(0,false).GetSign() == KH::_THEN){ //Gen if .. { } GenPush(" { "); skip(1); if(!StatementParsing()) Error( result," Statement Error , Statement required ."); //Gen if .. { } GenPush(" } "); } else{ Error( result," Statement Error , 'Then' required : " + GetWord(false).GetValue()); } } else{ Error( result," Statement Error , Condition required ."); } break; case KH::_WHILE: //Gen while GenPush(" while "); skip(1); if( ConditionParsing()){ if( GetWord(0,false).GetSign() == KH::_DO){ //Gen while .. {} GenPush(" { "); skip(1); if(!StatementParsing()) Error( result," Statement Error , Statement required ."); //Gen while .. {} GenPush(" } "); } else{ Error( result," Statement Error , 'Do' required : " + GetWord(false).GetValue()); } } else{ Error( result," Statement Error , Condition required ."); } break; case KH::_READ: skip(1); if( GetWord(0,false).GetSign() == KH::_LPAREN && GetWord(1,false).GetSign() == KH::_IDENTIFIER){ Sa.ExistVariable(GetLine(),GetWord(1,false).GetValue()); //Gen read GenPush(" scanf(\"%lf\" , &" + GetWord(1,false).GetValue() + ") ;"); skip(2); while( GetWord(0,false).GetSign() == KH::_COMMA){ skip(1); if( GetWord(0,false).GetSign() == KH::_IDENTIFIER){ Sa.ExistVariable(GetLine(),GetWord(false).GetValue()); //Gen read GenPush(" scanf(\"%lf\" , &" + GetWord(0,false).GetValue() + ") ;"); skip(1); } else Error( result," Statement Error , Identifire required : " + GetWord(false).GetValue()); } if( GetWord(0,false).GetSign() == KH::_RPAREN ) { skip(1); } else Error( result," Statement Error , ')' required : " + GetWord(false).GetValue()); } else{ Error( result," Statement Error , Identifire required : " + GetWord(false).GetValue()); } break; case KH::_WRITE: skip(1); if( GetWord(0).GetSign() == KH::_LPAREN ){ //Gen write(.. GenPush(" printf(\"%g \\n \" , "); skip(1); if(ExpressionParsing()){ //Gen write .. a .. GenPush(" ) ;"); while( GetWord(0,false).GetSign() == KH::_COMMA){ //Gen write .. , GenPush(" printf(\"%g \\n \" , "); skip(1); if(!ExpressionParsing()) Error( result," Statement Error , 【Expression required】 ."); //Gen write .. , GenPush(" ) ; "); } } else { Error( result," Statement Error , 【First Expression required】 ."); } if( GetWord(0,false).GetSign() == KH::_RPAREN ) { skip(1); } else Error( result," Statement Error , 【Right Paren required】 ."); } else{ Error( result," Statement Error , 【Left Paren required】 ."); } break; case KH::_SEMICOLON: skip(1); break; default: Error( result," Statement Error , 【Unexpected word " + GetWord(0,false).GetValue() + "】 .",false); break; } return result; }
//分程序语法判断 bool KH::GrammarPL0::Block(){ bool result = true; if( GetWord(false).GetSign() == KH::_BLOCK) skip(1); //自然会跳过所有的block if( CheckEnd()) { Error( result, " Empty Input ! " ); return false; } if( GetWord(false).GetSign() == KH::_CONST){ skip(1); if( GetWord(false).GetSign() == KH::_IDENTIFIER){ if( GetWord(1,false).GetSign() == KH::_ASSIGN && GetWord(2,false).GetSign() == KH::_INT || GetWord(2,false).GetSign() == KH::_FLOAT ) { Sa.PushVariable(GetLine(),GetWord(false).GetValue()); //Gen int a = 11 if(GetWord(2,false).GetSign() == KH::_INT) GenPush("const int " + GetWord(false).GetValue() + " = " + GetWord(2,false).GetValue() + "; " ); else GenPush("const float " + GetWord(false).GetValue() + " = " + GetWord(2,false).GetValue() + "; " ); skip(3,false); while( GetWord(false).GetSign() == KH::_COMMA){ if( GetWord(1,false).GetSign() == KH::_IDENTIFIER && GetWord(2,false).GetSign() == KH::_ASSIGN && GetWord(3,false).GetSign() == KH::_INT || GetWord(3,false).GetSign() == KH::_FLOAT ) { Sa.PushVariable(GetLine(),GetWord(1,false).GetValue()); //Gen , int a = 11 if(GetWord(3,false).GetSign() == KH::_INT) GenPush("const int " + GetWord(1,false).GetValue() + " = " + GetWord(3,false).GetValue() + "; " ); else GenPush("const float " + GetWord(1,false).GetValue() + " = " + GetWord(3,false).GetValue() + "; " ); skip(4,false); } else { Error( result, " Const Loop Error : " + GetWord(false).GetValue() + GetWord(1,false).GetValue() + GetWord(2,false).GetValue() + GetWord(3,false).GetValue() ); break; } } if( GetWord(false) == KH::_SEMICOLON) skip(1); else{ Error( result, " Const Not End : " + GetWord(false).GetValue() ); } } else { Error( result, " Const sentence Error : " + GetWord(false).GetValue() ); } } else { Error( result, " Const Identifier Error : " + GetWord(false).GetValue() + GetWord(1,false).GetValue() + GetWord(2,false).GetValue() ); } }//End of if const ; if( GetWord(false).GetSign() == KH::_VAR)//如果单词是"var" { skip(1);//取下一个单词 if( GetWord(false).GetSign() == KH::_IDENTIFIER){ Sa.PushVariable(GetLine(),GetWord(false).GetValue()); //Gen var a GenPush("double " + GetWord(false).GetValue() + " = 0 ; " ); skip(1); while( GetWord(false).GetSign() == KH::_COMMA){ if( GetWord(1,false).GetSign() == KH::_IDENTIFIER ) { Sa.PushVariable(GetLine(),GetWord(1,false).GetValue()); //Gen var .. , a GenPush("double " + GetWord(1,false).GetValue() + " = 0 ; " ); skip(2); } else { Error( result," Var Loop Error : " + GetWord(false).GetValue() + GetWord(1,false).GetValue()); break; } } if( GetWord(false).GetSign() == KH::_SEMICOLON){ skip(1); } else { Error( result," Var Not End : " + GetWord(false).GetValue() ); } } else { Error( result," Var Identifier Error : " + GetWord(false).GetValue() ); } }//End of if var while ( GetWord(false).GetSign() == KH::_PROC)//如果单词是"procedure",则进入"函数定义"语法分析 { skip(1); if( GetWord(false).GetSign() == KH::_IDENTIFIER && GetWord(1,false).GetSign() == KH::_SEMICOLON)//"procedure"后应为标识符 { Sa.PushVariable(GetLine(),GetWord(false).GetValue()); //Gen var .. , a GenPush("double " + GetWord(false).GetValue() + "( ) { " ); //注意闭合! funcNames.push_back(GetWord(false).GetValue()); skip(2); Block(); //Gen var .. , a GenPush(" return 0 ; } " ); //注意闭合! } else{ Error( result," Proc define Error : " + GetWord(false).GetValue() + GetWord(1,false).GetValue() ) ; } }//End of if procedure if(!StatementParsing()){ Error( result," Parsing Error . " ); }//End of if Parsing return result; }
void allocate(int datareg, int addreg, int floatreg, SNODE *block) /* * allocate will allocate registers for the expressions that have * a high enough desirability. It also puts the function * header, consisting of saved registers and stack decrments for local * variables */ { CSE *csp; ENODE *exptr; unsigned mask, rmask, i, fmask, frmask, size; AMODE *ap, *ap2; mask = asmMask; rmask = asmRMask; fmask = frmask = 0; for (i = cf_freedata; i < datareg; i++) { rmask = rmask | (1 << (15-i)); mask = mask | (1 << i); } for (i = cf_freeaddress + 16; i < addreg; i++) { rmask = rmask | (1 << (23-i)); mask = mask | (1 << (i - 8)); } while (bsort(&olist)) ; /* sort the expression list */ csp = olist; while (csp != 0) { if (csp->reg == - 1 && !(csp->exp->cflags &DF_VOL) && !csp->voidf) { if (desire(csp) < 3) csp->reg = - 1; else { if (csp->exp->nodetype == en_rcon || csp->exp->nodetype == en_fcon || csp->exp->nodetype == en_lrcon || csp->exp ->nodetype == en_floatref || csp->exp->nodetype == en_doubleref || csp->exp->nodetype == en_longdoubleref || csp->exp->nodetype == en_fimaginarycon || csp->exp->nodetype == en_rimaginarycon || csp->exp->nodetype == en_lrimaginarycon || csp->exp->nodetype == en_fimaginaryref || csp->exp->nodetype == en_rimaginaryref || csp->exp->nodetype == en_lrimaginaryref) {} else if ((csp->duses <= csp->uses / 4) && (datareg < cf_maxdata) && dataregs) csp->reg = (datareg)++; else if (!(csp->size == 1 || csp->size == - 1 || csp->size == 5) && (addreg < cf_maxaddress) && addrregs) csp->reg = (addreg)++; else if ((datareg < cf_maxdata) && dataregs) csp->reg = (datareg)++; if (csp->reg != - 1) // if (lvalue(csp->exp)) // csp->seg = defseg(csp->exp->v.p[0]) ; // else if (!csp->seg) { csp->seg = defseg(csp->exp); if (csp->seg) csp->reg = -1; } } } if (csp->reg != - 1) { if (lvalue(csp->exp) && !((SYM*)csp->exp->v.p[0]->v.p[0])->funcparm) { ((SYM*)csp->exp->v.p[0]->v.p[0])->mainsym->inreg = TRUE; ((SYM*)csp->exp->v.p[0]->v.p[0])->mainsym->value.i = - csp ->reg - (csp->size < 0 ? - csp->size: csp->size) *256; } if (csp->reg < 16) { rmask = rmask | (1 << (15-csp->reg)); mask = mask | (1 << csp->reg); } if (csp->reg < 32) { rmask = rmask | (1 << (23-csp->reg)); mask = mask | (1 << (csp->reg - 8)); } else { frmask = frmask | (1 << (39-csp->reg)); fmask = fmask | (1 << (csp->reg - 32)); } } csp = csp->next; } allocstack(); /* Allocate stack space for the local vars */ floatstack_mode = 0; /* no space for floating point temps */ if (currentfunc->intflag || currentfunc->faultflag) { mask = 0; rmask = 0; if (currentfunc->loadds) loadds(); if (prm_farkeyword) { GenPush(ES + 24, am_dreg, 0); GenPush(FS + 24, am_dreg, 0); GenPush(GS + 24, am_dreg, 0); } gen_code(op_pushad, 0, 0); } if ((conscount || try_block_list || currentfunc->value.classdata.throwlist && currentfunc->value.classdata.throwlist->data) && prm_xcept) { xceptoffs = lc_maxauto += sizeof(XCEPTDATA); } if (prm_debug) { rmask = rmask | (1 << (15-EBX)); mask = mask | (1 << EBX); rmask = rmask | (1 << (15-ESI-4)); mask = mask | (1 << (ESI+4)); rmask = rmask | (1 << (15-EDI-4)); mask = mask | (1 << (EDI+4)); } if (prm_cplusplus && prm_xcept || (funcfloat || lc_maxauto || currentfunc ->tp->lst.head && currentfunc->tp->lst.head != (SYM*) - 1) || (currentfunc->value.classdata.cppflags &PF_MEMBER) && !(currentfunc ->value.classdata.cppflags &PF_STATIC) || !prm_smartframes || !stackframeoff) { /* enter is *really* inefficient so we will not use it */ if (!currentfunc->intflag) gen_codes(op_push, 4, makedreg(EBP), 0); gen_codes(op_mov, 4, makedreg(EBP), makedreg(ESP)); if (lc_maxauto) gen_code(op_sub, makedreg(ESP), make_immed(lc_maxauto)); // FIXME ... could auto-alloc an FP value when no frame! frame_ins = peep_tail; } else frame_ins = 0; if (mask != 0) PushRegs(rmask); save_mask = mask; if (fmask != 0) fsave_mask = fmask; if (currentfunc->loadds && !currentfunc->intflag) { loadds(); } if (prm_stackcheck && lc_maxauto) { AMODE *ap1; ap = set_symbol("__stackerror", 1); ap1 = set_symbol("__stackbottom", 0); ap1->mode = am_direct; gen_codes(op_cmp, 4, makedreg(ESP), ap1); gen_codes(op_jb, 0, ap, 0); } AddProfilerData(); if ((conscount || try_block_list || currentfunc->value.classdata.throwlist && currentfunc->value.classdata.throwlist->data) && prm_xcept) { currentfunc->value.classdata.conslabel = nextlabel++; currentfunc->value.classdata.destlabel = nextlabel++; gen_codes(op_mov, 4, makedreg(EAX), make_label(nextlabel - 2)); call_library("__InitExceptBlock"); gen_label(nextlabel - 1); } }