⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.y

📁 一个面向对像语言的编译器
💻 Y
📖 第 1 页 / 共 2 页
字号:
								Declaration *tDecl=paraList->Nth(i);
								cg->SetParaOffset(tDecl);
							}
							cg->GenBeginFunc(d);
							cg->InitLocalOffset();
							
							char *temp=cg->NewLabel();
							cg->PushRetLabel(temp);
						}
                        StmtBlock
                        { 
							Declaration *funDecl;
							funDecl=$<decl>6;

							//设置函数local域的stack size
							funDecl->SetStackFrameSize(cg->GetStackFrameSize(LocalStackSize));
							scopes->PopScope();
							
							cg->GenLabel(cg->GetRetTopLabel());	
							cg->GenEndFunc(funDecl);
							cg->PopRetLabel(1);
						}
                ;

StmtBlock       :       '{' 
                        {
						 scopes->PushScope(new Scope(Scope::Local)); 
						}
                        StmtList '}'
                        { scopes->PopScope(); }
                ;
	
StmtList        :       StmtList Stmt 
                |       /* empty */
                ;

Stmt            :       VariableDecl
						{}						
                |       SimpleStmt ';' {}
                |       IfStmt      {}
                |       WhileStmt	{}
                |       ForStmt		{}
                |       ReturnStmt ';' {}
                |       StmtBlock	{}
                |       PrintStmt ';' {}
                |       BreakStmt {}
                ;
 
SimpleStmt      :       LValue '=' Expr
						{
							Declaration *debug1, *debug2;
							debug1 = $1, debug2 = $3;
							
							//LValue是地址的情况
							if($1->IsAddr())
							{
								if($3->IsAddr())
								{
									cg->GenAssign($1, $3);
								}
								else
								{
									cg->GenStore($1,$3);
								}
							}
							//LValue不是地址的情况
							else
							{
								if($3->IsAddr())
								{
									Declaration *decl=cg->GenLoad($3, $3->GetType());
									cg->GenAssign($1, decl);
								}
								else
									cg->GenAssign($1,$3);
							}
						}
                |       Expr 
						{
								
						}

                |       /* empty */ 
						{}
                ;

OptReceiver     :       Expr '.' 
						{
							Declaration *temp=$1;
							$$=$1;
						}
                |       /* empty */
						{$$=NULL;} 
                ; 

LValue          :       OptReceiver T_Identifier 
						{
							//调用semantic.cpp中的函数处理LValue
							$$=DealWithLValue($1, $2);							
						}
                |       Expr '[' Expr ']'
						{
							//调用semantic.cpp中的函数处理数组引用的情况
							$$=DealWithArray($1,$3);
						}
                ;

Call            :       OptReceiver T_Identifier '(' Actuals ')'
						{
							//调用semantic.cpp中的函数处理函数调用
							$$=DealWithCall($1, $2, $4);
						}
                ;

Expr            :       LValue		
						{
							if($1->IsAddr())
							{
								Declaration *decl=cg->GenLoad($1, $1->GetType());
								$$=decl;
							}
							else
								$$=$1;
						}

                |       Call		
						{
							$$=$1;
						}
                |       Constant	{$$ = $1;}
                |       Expr '+' Expr
						{$$=cg->GenBinaryOp("+", $1, $3, $1->GetType());}
                |       Expr '-' Expr
						{$$=cg->GenBinaryOp("-", $1, $3, $1->GetType());}
                |       Expr '/' Expr
						{$$=cg->GenBinaryOp("/", $1, $3, $1->GetType());}
                |       Expr '*' Expr
						{$$=cg->GenBinaryOp("*", $1, $3, $1->GetType());}
                |       Expr '%' Expr
						{$$=cg->GenBinaryOp("%", $1, $3, Type::intType)}
                |       Expr T_Equal Expr
						{

							Declaration *dec1=$1, *dec2=$3;
							//整形数的比较
							if($1->GetType()->IsEquivalentTo(Type::intType))
								$$=cg->GenBinaryOp("==", $1, $3, Type::boolType);
							
							//字符串的比较
							if($1->GetType()->IsEquivalentTo(Type::stringType))
							{
								cg->GenPushParam($3);
								cg->GenPushParam($1);
								$$=cg->GenLCall("_StringEqual", VarSize*2, Type::boolType);
							}
							
							//类类型的比较
							if(($1->GetType()->IsClassType())&&($3->GetType()->IsClassType()))
							{
								$$=cg->GenBinaryOp("==", $1, $3, Type::boolType);
							}	
						}
                |       Expr T_NotEqual Expr
						{
							Declaration *dec1, *dec2;
							//处理int型数
							if($1->GetType()->IsEquivalentTo(Type::intType))
							{
								dec1=cg->GenBinaryOp("<", $1, $3, Type::boolType);
								dec2=cg->GenBinaryOp("<", $3, $1, Type::boolType);
								$$=cg->GenBinaryOp("||", dec1, dec2, Type::boolType);
							}

							//处理string类型
							if($1->GetType()->IsEquivalentTo(Type::stringType))
							{
								cg->GenPushParam($3);
								cg->GenPushParam($1);
								dec1=cg->GenLCall("_StringEqual", VarSize*2, Type::boolType);
								dec2=cg->GenLoadConstant(1, Type::intType);
								$$=cg->GenBinaryOp("-", dec2, dec1, Type::boolType);
							}
							//处理类类型

							if(($1->GetType()->IsClassType())&&($3->GetType()->IsClassType()))
							{
								dec1=cg->GenBinaryOp("==", $1, $3, Type::boolType);
								dec2=cg->GenLoadConstant(1, Type::intType);
								$$=cg->GenBinaryOp("-", dec2, dec1, Type::boolType);
							}	

						}
                |       Expr '<' Expr
						
						{$$=cg->GenBinaryOp("<", $1, $3, Type::boolType);}

                |       Expr '>' Expr
						{$$=cg->GenBinaryOp("<", $3, $1, Type::boolType);}
                |       Expr T_LessEqual Expr
						{
							Declaration *dec1, *dec2;
							dec1=cg->GenBinaryOp("<", $1, $3, Type::boolType);
							dec2=cg->GenBinaryOp("==", $1, $3, Type::boolType);
							$$=cg->GenBinaryOp("||", dec1, dec2, Type::boolType);
						}
                |       Expr T_GreaterEqual Expr
						{
							Declaration *dec1, *dec2;
							dec1=cg->GenBinaryOp("<", $3, $1, Type::boolType);
							dec2=cg->GenBinaryOp("==", $1, $3, Type::boolType);
							$$=cg->GenBinaryOp("||", dec1, dec2, Type::boolType);
						}
                |       Expr T_And Expr
						{$$=cg->GenBinaryOp("&&", $1, $3, Type::boolType);}
                |       Expr T_Or Expr
						{$$=cg->GenBinaryOp("||", $1, $3, Type::boolType);}
                |       '(' Expr ')' 
						{$$ = $2;}
                |       '-' Expr  %prec T_UnaryMinus
						{
							Declaration *dec;
							dec=cg->GenLoadConstant(0, Type::intType);
							$$=cg->GenBinaryOp("-", dec, $2, Type::intType);
						}
                |       '!' Expr
						{
							Declaration *dec;
							dec=cg->GenLoadConstant(0, Type::boolType);
							$$=cg->GenBinaryOp("==", dec, $2, Type::boolType);
						}
				|       T_ReadInteger '(' ')'
						{
							$$=cg->GenBuiltInCall(ReadInteger, Type::intType);
						}
                |       T_ReadLine '(' ')'
						{
							$$=cg->GenBuiltInCall(ReadLine, Type::stringType);
						}
                |       T_This
						{
							$$=scopes->Lookup("this");
						}
                |       T_New '(' T_Identifier ')'
						{
							Declaration *dec1, *dec2, *dec3;
							dec1=scopes->Lookup($3);
							dec2=cg->GenLoadConstant(dec1->GetStackFrameSize(), Type::intType);
							dec3=cg->GenBuiltInCall(Alloc, dec1->GetType(), dec2);
							cg->GenStore(dec3, cg->GenLoadLabel($3));
							$$=dec3;
						}
                |       T_NewArray '(' Expr ',' Type ')'
						{
							//数组的分配过程按ppt中的过程写
							Declaration *dec1, *dec2, *dec3, *dec4, *dec5, *dec6, *dec7;
							$<label>$=cg->NewLabel();
							char *debug =$<label>$;
							dec1=cg->GenLoadConstant(0, Type::intType);
							dec2=cg->GenBinaryOp("<", $3, dec1, Type::boolType);
							
							
							cg->GenIfZ(dec2, $<label>$);

							dec3=cg->GenLoadConstant(err_arr_neg_size);
							cg->GenPushParam(dec3);
							cg->GenLCall("_PrintString",VarSize,Type::voidType);
							cg->GenLCall("_Halt", 0, Type::voidType);

							cg->GenLabel($<label>$);
							
							dec4=cg->GenLoadConstant(VarSize, Type::intType);
							dec5=cg->GenBinaryOp("*", dec4, $3, Type::intType);
							dec6=cg->GenBinaryOp("+", dec4, dec5, Type::intType);
							dec7=cg->GenBuiltInCall(Alloc,Type::NewArrayType($5),dec6);
							
							cg->GenStore(dec7, $3);
							$$=dec7;
							//$$->ValidateAddr();
						}
                ;
	
Constant        :       T_IntConstant 
                        { $$ = cg->GenLoadConstant($1, Type::intType);}
                |       T_BoolConstant
						{ $$ = cg->GenLoadConstant($1, Type::boolType);} 
                |       T_DoubleConstant 
                        { ReportError(&@1, err_no_code_gen_for_doubles); }
                |       T_StringConstant
						{ $$ = cg->GenLoadConstant($1);}
                |       T_Null
						{ $$ = cg->GenLoadConstant(0, Type::nullType);}
                ;

Actuals         :       ExprList
						{$$=$1;}
                |       /* empty */ 
						{$$=new DeclList();}
                ;

ExprList        :       ExprList ',' Expr
						{ $1->Append($3); $$=$1;}
                |       Expr
						{ $$ = new DeclList; $$->Append($1);}
                ;

BoolExpr        :       Expr
						{$$ = $1;}
                ;
    
WhileStmt       :       T_While
						{
							char *WhileBegin, *WhileEnd;
							WhileBegin=cg->NewLabel();
							WhileEnd=cg->NewLabel();
							cg->PushLabel(WhileBegin);
							cg->PushLabel(WhileEnd);
							cg->GenLabel(WhileBegin);
						}
						'(' BoolExpr ')'
						{
							char *WhileEnd=cg->GetLabel(0);
							cg->GenIfZ($4, WhileEnd);
						}
                        Stmt
						{
							char *WhileBegin, *WhileEnd;
							WhileBegin=cg->GetLabel(1);
							WhileEnd=cg->GetLabel(0);
							cg->GenGoto(WhileBegin);
							cg->GenLabel(WhileEnd);
							cg->PopLabel(2);
						}
                ;

ForStmt         :       T_For '(' SimpleStmt ';'			
						{
							char *temp;
							for(int i=0; i<4; i++)
							{
								temp=cg->NewLabel();
								cg->PushLabel(temp);
							}			
							cg->GenLabel(cg->GetLabel(0));
						}
                        BoolExpr ';'						
						{
							cg->GenIfZ($6,cg->GetLabel(3));
							cg->GenGoto(cg->GetLabel(2));
							cg->GenLabel(cg->GetLabel(1));	
						}
                        SimpleStmt							
						{
							cg->GenGoto(cg->GetLabel(0));
									
							cg->GenLabel(cg->GetLabel(2));				
						}
						')'									
                        Stmt								
						{
							cg->GenGoto(cg->GetLabel(1));
							cg->GenLabel(cg->GetLabel(3));
							cg->PopLabel(4);
						}
                ;

BreakStmt       :       T_Break ';'	
						{
							char *temp=cg->GetTopLabel();
							cg->GenGoto(cg->GetTopLabel());
						}						
                ;

IfStmt          :       T_If '(' BoolExpr ')'
						{
							$<label>$=cg->NewLabel();
							cg->GenIfZ($3, $<label>$);
						} 
						Stmt 
						{
							$<label>$=cg->NewLabel();
							cg->GenGoto($<label>$);
							cg->GenLabel($<label>5);
						}
						OptElse
						{
							cg->GenLabel($<label>7);
						}
                ;

OptElse         :       T_Else Stmt 
                |       /* empty */   %prec T_Lower_Than_Else 
                ;

ReturnStmt      :       T_Return Expr
						{
							Declaration *temp=$2;
							cg->GenReturn($2);

							//处理函数中间有return的情况
							cg->GenGoto(cg->GetRetTopLabel());	
						} 
                |       T_Return
						{
							cg->GenReturn();
							//处理函数中间有return的情况
							cg->GenGoto(cg->GetRetTopLabel());	
						}
                ;

PrintStmt       :       T_Print '(' ExprList ')'
						{
							//调用semantic.cpp中的函数处理print
							DealWithPrint($3);
						}
                ;

 

%%

/*
 * Function: Inityyparse()
 * -----------------------
 * This function will be called before any calls to yyparse().  It is designed
 * to give you an opportunity to do anything that must be done to initialize
 * the parser (set global variables, configure starting state, etc.). One
 * thing it already does for you is assign the value of the global variable
 * yydebug that controls whether yacc prints debugging information about
 * parser actions (shift/reduce) and contents of state stack during parser.
 * If set to false, no information is printed. Setting it to true will give
 * you a running trail that might be helpful when debugging your parser.
 * Please be sure the variable is set to false when submitting your final
 * version.
 */
void Inityyparse(void)
{
  PrintDebug("parser", "Initializing parser");
  //yydebug = false;
  scopes = new ScopeStack;
  cg = new CodeGenerator;
}

  /* pp4: you can define helper functions here to help perform tasks
   *      for code generation, but we prefer you to put those functions
   *      in the codegen module and keep the yacc file tidy!
   */
 





















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -