📄 parser.y
字号:
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 + -