Exemple #1
0
void block(int pIndex)		/* pIndex はこのブロックの関数名のインデックス */
{
	int backP;
	backP = genCodeV(jmp, 0);		/* 内部関数を飛び越す命令、後でバックパッチ */
	while (1) {				/* 宣言部のコンパイルを繰り返す */
		switch (token.kind){
		case Const:			/* 定数宣言部のコンパイル */
			token = nextToken();
			constDecl(); continue;
		case Var:				/* 変数宣言部のコンパイル */
			token = nextToken();
			varDecl(); continue;
		case Func:				/* 関数宣言部のコンパイル */
			token = nextToken();
			funcDecl(); continue;
		default:				/* それ以外なら宣言部は終わり */
			break;
		}
		break;
	}			
	backPatch(backP);			/* 内部関数を飛び越す命令にパッチ */
	changeV(pIndex, nextCode());	/* この関数の開始番地を修正 */
	genCodeV(ict, frameL());		/* このブロックの実行時の必要記憶域をとる命令 */
	statement();				/* このブロックの主文 */		
	genCodeR();				/* リターン命令 */
	blockEnd();				/* ブロックが終ったことをtableに連絡 */
}	
Exemple #2
0
void fncDecl_end(void) /* 関数出口処理 */
{
  backPatch(fncPt->adrs, -localAdrs);   /* フレームサイズ後埋(関数先頭はADBR) */
  if (last_statement != Return) {                   /* 関数末尾にreturnがない */
    if (IS_MAIN(fncPt)) gencode2(LDI, 0);             /* main関数なら戻値設定 */
    else if (fncPt->dtTyp != VOID_T)                    /* 本処理系の独自仕様 */
      err_s("本処理系では非void型関数の末尾には単独のreturn文が必要です。");
  }
  backPatch_RET(fncPt->adrs);           /* RET命令列へ飛ぶJMPの飛先番地を後埋 */
  gencode3(LOD, LOCAL_F, 0);                  /* 戻番地をオペランドスタックへ */
  gencode2(ADBR, localAdrs);                                /* フレームを解放 */
  gencode1(RET);                                                  /* 戻り命令 */
}
Exemple #3
0
void set_main(void) /* main関数処理 */
{
  if (fncPt->dtTyp != INT_T || fncPt->args != 0)       /* 型と引数個数の確認 */
    err_s("main関数の書式が不正");
  backPatch(0, fncPt->adrs);                   /* 0番地のCALL命令の番地を後埋 */
}
Exemple #4
0
//进行规约的操作
bool LRGramar::doGuiYue(const int ruleNum)
{
    switch(ruleNum)
    {
    case  R1:
        //执行进出站等相关操作
        if(!doRules(A_NTERMINAL,4))
        {
            return false;
        }
        break;
    case R2:
        if(!doRules(B_NTERMINAL,3))
        {
            return false;
        }
        break;
    case R3:
        if(!doRules(C_NTERMINAL,3))
        {
            return false;
        }
        break;
    case R4:
        if(!doRules(C_NTERMINAL,0))
        {
            return false;
        }
        break;
    case R5:
        if(!doRules(D_NTERMINAL,1))
        {
            return false;
        }
        break;
    case R6:
    case R7:
        if(!doRules(D_NTERMINAL,1))
        {
            return false;
        }
        else
        {

        }
        break;
    case R8:
        if(!doRules(F_NTERMINAL,3))
        {
            return false;
        }
        else
        {
            //堆栈是先进先出
            int argP = variableBufferPtr--;
            int resultPtr = variableBufferPtr--;
            emit("=",variableBuffer[argP]," ",variableBuffer[resultPtr]);
        }
        break;
    case R9:
        if(!doRules(G_NTERMINAL,2))
        {
            return false;
        }
        else
        {
            backPatch(trueChainHead,nextq);  //回填真链头
        }
        break;
    case R10:
        if(!doRules(S_NTERMINAL,2))
        {
            return false;
        }
        else
        {
            backPatch(falseChain[falseChainPtr--],nextq);
        }
        break;
    case R11:
        if(!doRules(T_NTERMINAL,3))
        {
            return false;
        }
        else
        {

            emit("goto","","","0");
            backPatch(falseChain[falseChainPtr--],nextq);
            falseChain[++falseChainPtr] = nextq-1;
        }
        break;
    case R12:
        if(!doRules(S_NTERMINAL,2))
        {
            return false;
        }
        backPatch(falseChain[falseChainPtr--],nextq);
        break;
    case R13:
        if(!doRules(W_NTERMINAL,2))
        {
            return false;
        }
        else
        {
            backPatch(trueChainHead,doTrue[doTruePtr--]);
            backPatch(falseChain[falseChainPtr--],nextq);
        }
        break;
    case R14:
        if(!doRules(K_NTERMINAL,1))
        {
            return false;
        }
        doTrue[++doTruePtr] = nextq;//保存do后面的地址
        break;
    case R15:
        if(!doRules(L_NTERMINAL,2))
        {
            return false;
        }
        break;
    case R16:
        if(!doRules(N_NTERMINAL,2))
        {
            return false;
        }
        break;
    case R17:
        if(!doRules(Q_NTERMINAL,3))
        {
            return false;
        }
        else
        {
            trueChainHead = nextq;
            falseChain[++falseChainPtr]=nextq+1;
            char temp[10];
            int arg2 = variableBufferPtr--;
            int arg1 = variableBufferPtr--;
            sprintf(temp,"%s%s%s",variableBuffer[arg1],lastOp[OpPtr--],variableBuffer[arg2]);
            emit("if",temp,"goto","0");
            emit("goto","","","0");

        }
        break;
    case R18:
        if(!doRules(P_NTERMINAL,2))
        {
            return false;
        }
        else
        {
            if(strcmp(variableBuffer[variableBufferPtr],"null")!=0)
            {
                char *pPlace = newTemp();
                emit(lastOp[OpPtr--],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],pPlace);
                strcpy(variableBuffer[++variableBufferPtr],pPlace);
            }
            else {
                variableBufferPtr--;
            }
        }
        break;
    case R19:
        if(!doRules(H_NTERMINAL,3))
        {
            return false;
        }
        else
        {
            if(strcmp(variableBuffer[variableBufferPtr],"null")!=0)
            {
                char *hPlace = newTemp();
                emit(lastOp[OpPtr--],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],hPlace);
                strcpy(variableBuffer[++variableBufferPtr],hPlace);
            }
            else {
                variableBufferPtr--;
            }
            strcpy(lastOp[++OpPtr],"+");
        }
        break;
    case R20:
        if(!doRules(H_NTERMINAL,3))
        {
            return false;
        }
        else
        {
            if(strcmp(variableBuffer[variableBufferPtr],"null")!=0)
            {
                char *hPlace = newTemp();
                emit(lastOp[OpPtr--],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],hPlace);
                strcpy(variableBuffer[++variableBufferPtr],hPlace);
            }
            else
            {
                variableBufferPtr--;
            }
            strcpy(lastOp[++OpPtr],"-");
        }
        break;
    case R21:
        if(!doRules(H_NTERMINAL,0))
        {
            return false;
        }
        else
        {
            strcpy(variableBuffer[++variableBufferPtr],"null");
        }
        break;
    case R22:
        if(!doRules(Z_NTERMINAL,2))
        {
            return false;
        }
        else
        {
            if(strcmp(variableBuffer[variableBufferPtr],"null")!=0)
            {
                char *zPlace = newTemp();
                emit(lastOp[OpPtr--],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],zPlace);
                strcpy(variableBuffer[++variableBufferPtr],zPlace);
            }
            else
            {
                variableBufferPtr--;
            }
        }
        break;
    case R23:
        if(!doRules(V_NTERMINAL,3))
        {
            return false;
        }
        else
        {
            if(strcmp(variableBuffer[variableBufferPtr],"null")!=0)
            {
                char *vPlace = newTemp();
                emit(lastOp[--OpPtr],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],vPlace);
                strcpy(variableBuffer[++variableBufferPtr],vPlace);
            }
            else
            {
                variableBufferPtr--;
            }
            strcpy(lastOp[++OpPtr] ,"*");
        }
        break;
    case R24:
        if(!doRules(V_NTERMINAL,3))
        {
            return false;
        }
        else
        {
            if(strcmp(variableBuffer[variableBufferPtr],"null")!=0)
            {
                char *vPlace = newTemp();
                emit(lastOp[--OpPtr],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],vPlace);
                strcpy(variableBuffer[++variableBufferPtr],vPlace);
            }
            else
            {
                variableBufferPtr--;
            }
            strcpy(lastOp[++OpPtr] ,"/");
        }
        break;
    case R25:
    case R26:
        if(!doRules(U_NTERMINAL,1))
        {
            return false;
        }
        break;
    case R27:
        if(!doRules(U_NTERMINAL,3))
        {
            return false;
        }
        break;
    case R28:
        strcpy(lastOp[++OpPtr],"<");
        if(!doRules(Y_NTERMINAL,1))
        {
            return false;
        }
        break;
    case R29:
        if(!doRules(Y_NTERMINAL,1))
        {
            return false;
        }
        strcpy(lastOp[++OpPtr],"<=");
        break;
    case R30:
        if(!doRules(Y_NTERMINAL,1))
        {
            return false;
        }
        strcpy(lastOp[++OpPtr],">");
        break;
    case R31:
        if(!doRules(Y_NTERMINAL,1))
        {
            return false;
        }
        strcpy(lastOp[++OpPtr],">=");
        break;
    case R32:
        if(!doRules(Y_NTERMINAL,1))
        {
            return false;
        }
        strcpy(lastOp[++OpPtr],"==");
        break;
    case R33:
        if(!doRules(Y_NTERMINAL,1))
        {
            return false;
        }
        strcpy(lastOp[++OpPtr],"!=");
        break;
    case R34:
        if(!doRules(V_NTERMINAL,0))
        {
            return false;
        }
        else
        {
            strcpy(variableBuffer[++variableBufferPtr],"null");
        }
        break;
    default:
        return false;
    }
    return true;
}
Exemple #5
0
void statement(){
  int l;
  int m;
  symTableEntry* symbol;
  int tempLabels[2];
 
  if(currentToken == identsym){
    symbol = findSymbol(symTable, VAR, tokenVal.string, scope);
    if(!findVar(tokenVal.string, scope, &l, &m)){
      if(findConst(tokenVal.string, scope, &m))
        throwError(CANNOT_ASSIGN_TO_CONST_OR_PROC);
      else
        throwError(UNDEC_ID);
    }
    
    readToken();
    
    if(currentToken != becomessym)
      throwError(ASSIGN_EXPEC);
    
    readToken();
    
    expression();
 
    genCode(STO, l, m);
  }
  else if(currentToken == syawsym){
    readToken();
    
    if(currentToken != identsym)
      throwError(ID_FOLLOW_SYAW);

    if(!findFunc(tokenVal.string, scope, &l, &m))
      throwError(UNDEC_ID);

    genCode(CAL, l, m);
    
    readToken();
  }
  else if(currentToken == sngaisym){ // 'beginsym'
    readToken();
    
    statement();
    
    while(currentToken == semicolonsym){
      readToken();
      
      statement();
    }
      
    if(currentToken != fpesym && 
        (currentToken != identsym && currentToken != sngaisym
        && currentToken != txosym && currentToken != tengkrrsym)) // 'endsym'
      //throwError(WRONG_SYM_AFTER_STATE);
      throwError(SEMICOL_OR_RBRACK_EXPEC);
    else if(currentToken == identsym || currentToken == sngaisym
        || currentToken == txosym || currentToken == tengkrrsym)
      throwError(SEMICOL_BW_STATE_MISS);
    
    readToken();
  }
  else if(currentToken == txosym){ // 'ifsym'
    tempLabels[1] = 0;

    readToken();
    
    condition();
    
    tempLabels[0] = reserveCode(); //Conditional jump will go here
 
    if(currentToken != tsakrrsym) // 'thensym'
      throwError(TSAKRR_EXPEC);
    
    readToken();
    
    statement();

    if(currentToken == txokefyawsym){
      tempLabels[1] = reserveCode();
      readToken();
    }
 
    backPatch(tempLabels[0], JPC, 0, genLabel());
    
    if(tempLabels[1]){
      statement();
      backPatch(tempLabels[1], JMP, 0, genLabel());
    }

  }
  else if(currentToken == tengkrrsym){ // 'whilesym'
 
    readToken();
    
    tempLabels[0] = genLabel(); //Jump back up to here at the end of the loop
 
    condition();
 
    tempLabels[1] = reserveCode(); //Stick the conditional jump here
 
    if(currentToken != sisym) // 'dosym'
      throwError(SI_EXPEC);
    
    readToken();
      
    statement();
    
    genCode(JMP, 0, tempLabels[0]);
    backPatch(tempLabels[1], JPC, 0, genLabel());
  }
  else if(currentToken == misym){ // Input
    genCode(SIO, 0, 2);
    
    readToken();
    
    if(currentToken == identsym){
      if(findVar(tokenVal.string, scope, &l, &m))
        genCode(STO, l, m);
      else if(findConst(tokenVal.string, scope, &m)
              || findFunc(tokenVal.string, scope, &l, &m))
        throwError(CANNOT_STORE_IN_CONST_OR_PROC);
      else
        throwError(UNDEC_ID);
      
      readToken();
    }
  }
  else if(currentToken == wrrpasym){ // Output
    readToken();
    
    if(currentToken == identsym){
      if(findVar(tokenVal.string, scope, &l, &m))
        genCode(LOD, l, m);
      else if(findConst(tokenVal.string, scope, &m))
        genCode(LIT, 0, m);
      else
        throwError(UNDEC_ID);
      
      readToken();
    }
    
    genCode(SOI, 0, 1);
  }
  else if(currentToken == fpesym){
    return;
  }
  else{
    if(currentToken == periodsym)
      throwError(RBRACK_EXPEC_AT_END);
    else
      throwError(STATEMENT_EXPEC);
  }
  
  return;
}
Exemple #6
0
void block(){

  int jmpLoc = reserveCode();

  int thisScope;
  int numVars = 0;
  char tempSymbol[MAX_IDENT_LENGTH + 1];
 
  if(currentToken == constsym){
    /***************************************************************/
    /* const-declaration ::= [ "const" ident "=" number            */
    /*                               {"," ident "=" number} ";"]   */
    /***************************************************************/
    do{
      readToken();
      
      if(currentToken != identsym){
        throwError(ID_FOLLOW_CONST_VAR_PROC);
      }else{
        strcpy(tempSymbol, tokenVal.string);
      }
 
      readToken();
      
      if(currentToken != eqsym){
        if(currentToken == becomessym)
          throwError(EQ_NOT_BECOMES);
        else
          throwError(EQ_FOLLOW_ID);
      }
      
      readToken();
    
      if(currentToken != numbersym){
        throwError(NUM_FOLLOW_EQ);
      }else{
        insertSymbol(symTable, newSymbol(CONST, tempSymbol, scope, 0,
                                         tokenVal.numeric));
      }
    
      readToken();
    }while(currentToken == commasym);
    
    if(currentToken != semicolonsym)
      throwError(SEMICOL_COMMA_MISS);
 
    readToken();
  }
  
  if(currentToken == intsym){
    /*******************************************************/
    /* var-declaration ::= ["int" ident {"," ident} ";"] */
    /*******************************************************/
    do{
      readToken();
      
      if(currentToken != identsym){
        throwError(ID_FOLLOW_CONST_VAR_PROC);
      }else{
        insertSymbol(symTable, newSymbol(VAR, tokenVal.string,
                                         scope, BASE_OFFSET + numVars++, 0));
      }
        
      readToken();
    }while(currentToken == commasym);
    
    if(currentToken != semicolonsym)
      throwError(SEMICOL_COMMA_MISS);
      
    readToken();
  }
  
  //Saving the scope before moving into procedure declarations
  thisScope = scope;

  while(currentToken == procsym){
    /**********************************************************************/
    /* proc-declaration ::= {"procedure" ident ";" block ";"} statement   */
    /**********************************************************************/

    readToken();
    
    if(currentToken != identsym)
      throwError(ID_FOLLOW_CONST_VAR_PROC);

    //Storing the function name in the symbol table
    insertSymbol(symTable, newSymbol(FUNC, tokenVal.string, thisScope, 
                                     genLabel(), 0));

    
    readToken();
    
    if(currentToken != semicolonsym)
      throwError(SEMICOL_COMMA_MISS);
      
    readToken();

    //Incrementing the scope for our new function and saving its parent
    //in the disjoint set
    scope++;
    scopeParent[scope] = thisScope;

    block();
    
    if(currentToken != semicolonsym)
      throwError(WRONG_SYM_AFTER_PROC);
    
    readToken();
  }

  //Restoring the scope
  scope = thisScope;

  backPatch(jmpLoc, JMP, 0, genLabel());
  genCode(INC, 0, BASE_OFFSET + numVars);
 
  statement();
  
  genCode(OPR, 0, RET);
 
  return;
}
Exemple #7
0
void statement()			/* 文のコンパイル */
{
	int tIndex;
	KindT k;
	int backP, backP2;				/* バックパッチ用 */

	while(1) {
		switch (token.kind) {
		case Id:					/* 代入文のコンパイル */
			tIndex = searchT(token.u.id, varId);	/* 左辺の変数のインデックス */
			setIdKind(k=kindT(tIndex));			/* 印字のための情報のセット */
			if (k != varId && k != parId) 		/* 変数名かパラメタ名のはず */
				errorType("var/par");
			token = checkGet(nextToken(), Assign);			/* ":="のはず */
			expression();					/* 式のコンパイル */
			genCodeT(sto, tIndex);				/* 左辺への代入命令 */
			return;
		case If:					/* if文のコンパイル */
			token = nextToken();
			condition();					/* 条件式のコンパイル */
			token = checkGet(token, Then);		/* "then"のはず */
			backP = genCodeV(jpc, 0);			/* jpc命令 */
			statement();					/* 文のコンパイル */
			backPatch(backP);				/* 上のjpc命令にバックパッチ */
			return;
		case Ret:					/* return文のコンパイル */
			token = nextToken();
			expression();					/* 式のコンパイル */
			genCodeR();					/* ret命令 */
			return;
		case Begin:				/* begin . . end文のコンパイル */
			token = nextToken();
			while(1){
				statement();				/* 文のコンパイル */
				while(1){
					if (token.kind==Semicolon){		/* 次が";"なら文が続く */
						token = nextToken();
						break;
					}
					if (token.kind==End){			/* 次がendなら終り */
						token = nextToken();
						return;
					}
					if (isStBeginKey(token)){		/* 次が文の先頭記号なら */
						errorInsert(Semicolon);	/* ";"を忘れたことにする */
						break;
					}
					errorDelete();	/* それ以外ならエラーとして読み捨てる */
					token = nextToken();
				}
			}
		case While:				/* while文のコンパイル */
			token = nextToken();
			backP2 = nextCode();			/* while文の最後のjmp命令の飛び先 */
			condition();				/* 条件式のコンパイル */
			token = checkGet(token, Do);	/* "do"のはず */
			backP = genCodeV(jpc, 0);		/* 条件式が偽のとき飛び出すjpc命令 */
			statement();				/* 文のコンパイル */
			genCodeV(jmp, backP2);		/* while文の先頭へのジャンプ命令 */
			backPatch(backP);	/* 偽のとき飛び出すjpc命令へのバックパッチ */
			return;
		case Write:			/* write文のコンパイル */
			token = nextToken();
			expression();				/* 式のコンパイル */
			genCodeO(wrt);				/* その値を出力するwrt命令 */
			return;
		case WriteLn:			/* writeln文のコンパイル */
			token = nextToken();
			genCodeO(wrl);				/* 改行を出力するwrl命令 */
			return;
		case End: case Semicolon:			/* 空文を読んだことにして終り */
			return;
		default:				/* 文の先頭のキーまで読み捨てる */
			errorDelete();				/* 今読んだトークンを読み捨てる */
			token = nextToken();
			continue;
		}		
	}
}