?? c.y
字號(hào):
if ( sg_parameter_list )
// means this compound statement belong to a function, so...
// of course, if sg_parameter_list is NULL it also maybe a
// compound statement belong to a function because the parameters
// is void , heihei....
{
add_symbol_list_to_current_symtab(sg_parameter_list);
sg_parameter_list = NULL;
}
}
statement_list oRC
{
PARSE_INFO("statement_list oRC");
del_compound_symtab();
}
| oLC declaration_list
{
PARSE_INFO("compound_statement :oLC declaration_list ")
if ( sg_parameter_list )
// means this compound statement belong to a function, so...
// of course, if sg_parameter_list is NULL it also maybe a
// compound statement belong to a function because the parameters
// is void , heihei....
{
add_symbol_list_to_current_symtab( sg_parameter_list );
sg_parameter_list = NULL;
}
gen_var_assign_init($2);
}
oRC
{
PARSE_INFO("oRC");
yyerror("waring : compound statement has only declaration, no statements");
del_compound_symtab();
}
| oLC oRC
{
PARSE_INFO("compound_statement :oLC oRC")
if ( sg_parameter_list )
// means this compound statement belong to a function, so...
// of course, if sg_parameter_list is NULL it also maybe a
// compound statement belong to a function because the parameters
// is void , heihei....
{
add_symbol_list_to_current_symtab( sg_parameter_list );
sg_parameter_list = NULL;
}
yyerror("warning : compound statement is empty");
del_compound_symtab();
}
;
statement_list
: statement
{
PARSE_INFO("statement_list :statement")
}
| statement_list statement
{
PARSE_INFO("statement_list :statement_list statement")
}
;
selection_statement
: kIF oLP expression oRP
{
char lb_else[LABEL_LEN];
PARSE_INFO("selection_statement :kIF oLP expression ")
if ( !$3 )
{
yyerror("'if' expression can't be empty");
user_exit(1);
}
// mov ax, expression
gen_mov_value_to_reg($3, "ax");
// or ax, ax
gen_or("ax", "ax");
strcpy(lb_else, get_a_label());
// jz lab_else
gen_jump("jz", lb_else);
push_label(lb_else);
}
statement
{
char lb_end[LABEL_LEN];
PARSE_INFO("oRP statement ")
strcpy(lb_end, get_a_label());
// jmp lab_end
gen_jump("jmp", lb_end);
// lab_else:
gen_label(pop_label());
push_label(lb_end);
}
else_clause
{
PARSE_INFO("else_clause")
// lab_end:
gen_label(pop_label());
}
| kSWITCH oLP expression oRP
{
symbol *sw;
char lab_start[LABEL_LEN];
PARSE_INFO("selection_statement :kSWITCH oLP expression oRP ")
if ( !$3 )
{
yyerror("'switch' expression can't be empty");
user_exit(1);
}
sw = new_symbol();
// get end label
strcpy(sw->rname, get_a_label());
// get start lab
strcpy(lab_start, get_a_label());
push_label(lab_start);
push_switch(sw);
// push break label
push_break_label(sw->rname);
// jmp lab_start
gen_jump("jmp", lab_start);
}
statement
{
symbol *sw, *df = NULL, *tmp;
PARSE_INFO("statement")
// pop break label
pop_break_label();
sw = pop_switch();
// jmp lab_end
gen_jump("jmp", sw->rname);
// lab_start:
gen_label(pop_label());
// mov ax, $3
gen_mov_value_to_reg($3, "ax");
tmp = sw->next;
while (tmp)
{
if ( !IS_DEFAULT(tmp) )
{
// is case
// cmp ax, cl
gen_cmp_cl("ax", tmp->V_I);
// jz lab
gen_jump("jz", tmp->rname);
}
else
df = tmp;
tmp = tmp->next;
}
if ( df )
{
// has default
//jmp default
gen_jump("jmp", df->rname);
}
// lab_end:
gen_label(sw->rname);
remove_symbol_list(sw);
}
;
else_clause
: kELSE statement
{
PARSE_INFO("else_clause :kELSE statement")
}
|
{
PARSE_INFO("else_clause :")
}
;
iteration_statement
: kWHILE
{
char lb_start[LABEL_LEN];
PARSE_INFO("iteration_statement :kWHILE ")
strcpy(lb_start, get_a_label());
// lab_start:
gen_label(lb_start);
push_label(lb_start);
// set continue label
push_continue_label(lb_start);
}
oLP expression oRP
{
char lb_end[LABEL_LEN];
PARSE_INFO("oLP expression oRP ")
if ( !$4 )
{
yyerror("'while' expression can't be empty");
user_exit(1);
}
strcpy(lb_end, get_a_label());
// mov ax, expression
gen_mov_value_to_reg($4, "ax");
// or ax, ax
gen_or("ax", "ax");
// jz lab_end
gen_jump("jz", lb_end);
push_label(lb_end);
// set break flag
push_break_label(lb_end);
}
statement
{
char lb_end[LABEL_LEN];
PARSE_INFO("statement")
// clear break flag
pop_break_label();
// clear continue label
pop_continue_label();
strcpy(lb_end, pop_label());
// jmp lab_start
gen_jump("jmp", pop_label());
// lab_end:
gen_label(lb_end);
}
| kDO
{
char lb_start[LABEL_LEN], lb_end[LABEL_LEN];
PARSE_INFO("iteration_statement :kDO ")
strcpy(lb_start, get_a_label());
strcpy(lb_end, get_a_label());
push_label(lb_end);
// lab_start:
gen_label(lb_start);
push_label(lb_start);
// set continue label
push_continue_label(lb_start);
// set break label
push_break_label(lb_end);
}
statement kWHILE oLP expression oRP oSEMI
{
PARSE_INFO("statement kWHILE oLP expression oRP oSEMI")
if ( !$6 )
{
yyerror("'do ... while' expression can't be empty");
user_exit(1);
}
// clear break flag
pop_break_label();
// clear continue label
pop_continue_label();
// mov ax, expression
gen_mov_value_to_reg($6, "ax");
// or ax, ax
gen_or("ax", "ax");
// jnz lab_start
gen_jump("jnz", pop_label());
// lab_end:
gen_label(pop_label());
}
| kFOR oLP expression oSEMI
{
char lab_start[LABEL_LEN], lab_end[LABEL_LEN];
PARSE_INFO("iteration_statement :kFOR oLP expression oSEMI ")
GEN_END_EXPRESS($3)
strcpy(lab_start, get_a_label());
strcpy(lab_end, get_a_label());
// lab_start:
gen_label(lab_start);
// push continue stack
push_continue_label(lab_start);
// push break stack
push_break_label(lab_end);
}
expression oSEMI
{
char lab_body[LABEL_LEN], lab_step[LABEL_LEN];
PARSE_INFO("expression oSEMI ")
strcpy(lab_body, get_a_label());
strcpy(lab_step, get_a_label());
if ( $6 )
{
// mov ax, $6
gen_mov_value_to_reg($6, "ax");
// or ax, ax
gen_or("ax", "ax");
// jz lab_end
gen_jump("jz", get_break_stack_top());
}
// jmp body
gen_jump("jmp", lab_body);
// lab_step:
gen_label(lab_step);
// push label step
push_label(lab_step);
// push label body
push_label(lab_body);
}
expression oRP
{
PARSE_INFO("expression oRP ")
GEN_END_EXPRESS($9)
// jmp lab_start
gen_jump("jmp", get_continue_stack_top());
// lab_body:
gen_label(pop_label());
}
statement
{
PARSE_INFO("statement")
// jmp lab_step
gen_jump("jmp", pop_label());
// lab_end:
gen_label(get_break_stack_top());
// pop break stack
pop_break_label();
// pop continue stack
pop_continue_label();
}
;
jump_statement
: kGOTO identifier oSEMI
{
symbol *lb;
PARSE_INFO("jump_statement :kGOTO identifier oSEMI")
lb = search_goto_label($2);
if ( !lb )
{
// the label has not be define or refernece
// so, new symbol and add it to goto label symtab
lb = new_symbol();
lb->NOUN = SPEC_LABEL;
strcpy(lb->name, $2);
strcpy(lb->rname, get_a_label());
lb->is_declaration = 1;
add_goto_label(lb);
}
// jmp label
gen_jump("jmp", lb->rname);
}
| kCONTINUE oSEMI
{
char *lb;
PARSE_INFO("jump_statement :kCONTINUE oSEMI")
lb = get_continue_stack_top();
assert(lb);
// jmp lb
gen_jump("jmp", lb);
}
| kBREAK oSEMI
{
char *lb;
PARSE_INFO("jump_statement :kBREAK oSEMI")
lb = get_break_stack_top();
assert(lb);
// jmp lb
gen_jump("jmp", lb);
}
| kRETURN expression oSEMI
{
PARSE_INFO("jump_statement :kRETURN expression oSEMI")
gen_return_stmt($2);
}
expression
: assignment_expression
{
PARSE_INFO("expression :assignment_expression")
}
| expression oCOMMA
{
PARSE_INFO("expression :expression oCOMMA ")
if ( !$1 )
{
yyerror("missing ';' before ','");
user_exit(1);
}
GEN_END_EXPRESS($1)
del_symbol($1);
}
assignment_expression
{
PARSE_INFO("assignment_expression")
$$ = $4;
}
|
{
PARSE_INFO("expression :")
$$ = NULL;
}
;
assignment_expression
: conditional_expression
{
PARSE_INFO("assignment_expression :conditional_expression")
}
/* | unary_expression assignment_operator assignment_expression */
| unary_expression oASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oASSIGN assignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'=' : left operand must be l-value");
user_exit(1);
}
// mov ax, $3
gen_mov_value_to_reg($3, "ax");
if ( IS_ARRAY($1) )
gen_get_array_element($1);
// mov $1, ax
gen_mov_reg_to_var("ax", $1);
del_symbol($3);
// set rvalue flag
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push ax
gen_push_reg("ax");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
| unary_expression oPLUSASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oPLUSASSIGN ssignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'+=' : left operand must be l-value");
user_exit(1);
}
// mov ax, $3
gen_mov_value_to_reg($3, "ax");
if ( IS_ARRAY($1) )
gen_get_array_element($1);
// add ax, $1
gen_add("ax", $1->rname);
// mov $1, ax
gen_mov_reg_to_var("ax", $1);
del_symbol($3);
// set rvalue flag
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push ax
gen_push_reg("ax");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
| unary_expression oMINUSASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oMINUSASSIGN assignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'-=' : left operand must be l-value");
user_exit(1);
}
// mov dx, $3
gen_mov_value_to_reg($3, "dx");
// mov ax, $1
gen_mov_value_to_reg($1, "ax");
// sub ax, dx
gen_sub("ax", "dx");
// mov $1, ax
gen_mov_reg_to_var("ax", $1);
del_symbol($3);
// set rvalue flag
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push ax
gen_push_reg("ax");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
| unary_expression oMULASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oMULASSIGN assignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'*=' : left operand must be l-value");
user_exit(1);
}
// mov dx, $3
gen_mov_value_to_reg($3, "dx");
// mov ax, $1
gen_mov_value_to_reg($1, "ax");
// imul dx
gen_mul("dx");
// mov $1, ax
gen_mov_reg_to_var("ax", $1);
del_symbol($3);
// set rvalue flag
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push ax
gen_push_reg("ax");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
| unary_expression oDIVASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oDIVASSIGN assignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'/=' : left operand must be l-value");
user_exit(1);
}
// mov dx, $3
gen_mov_value_to_reg($3, "dx");
// mov ax, $1
gen_mov_value_to_reg($1, "ax");
// idiv dx
gen_div("dx");
// mov $1, ax
gen_mov_reg_to_var("ax", $1);
del_symbol($3);
// set rvalue flag
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -