하하하

14789 단어
void program()
{
	int entry_flag  = 0;
	Symbol *p, *q;
	
	/* before parse insert read && write func */
	p = insert_global_sym(FUNCTION,"read");
	q = insert_global_sym(FUNCTION,"write");
	if(!p || !q){
		fprintf(stderr, "init read write function error
"); exit(0); } token = get_token(); while(token == TOK_INT || token == TOK_PVOID || token == TOK_VOID || token == TOK_CHAR || token == TOK_PINT || token == TOK_PCHAR) { entry_flag = 1; declaration(token); } if(entry_flag){ gen_code("stp
"); printf("succeed!! exit()
"); }else{ fprintf(stderr, "line %d: %s does not name a type
", save_line, save_word ); } } static void declaration(int type) { GlobalInfo *global_var; char id[NAME_SIZE]; type = token; match(type); match(TOK_ID); strncpy(id, save_word, NAME_SIZE); if(token == TOK_LPAREN){ fun_declaration(type, id); if(!strcmp(id,"main")){ main_stack = current_function->u.f.total_offset; } } else if(token == TOK_SEMI || token == TOK_LSQUARE) { global_var = global_var_declaration(type, id); global_var->seq = global_seq; global_var->offset = global_total_offset; global_total_offset += global_var->size; global_seq++; } else{ fprintf(stderr, "line %d: unexpected token %s
", save_line, save_word); } } static void fun_declaration(int type, char * id) { if(type != TOK_VOID) has_return_value = false; // init AutoOffset memset(&offset,0,sizeof(AutoOffset)); current_function = insert_global_sym(FUNCTION,id); if(current_function == NULL) { //insert_func failed! } current_function->u.f.return_type = type; gen_code("ent %d
", current_function->u.f.id); /* match ( */ match(TOK_LPAREN); params(); /*match ) */ match(TOK_RPAREN); //add after insert auto_var //current_function->u.f.total_offset += current_function->u.f.param_size; compound_stmt(); if(current_function->u.f.return_type == TOK_VOID && has_return_value){ fprintf(stderr, "line %d: this fuction doesn't return value'
", save_line); } } static GlobalInfo* global_var_declaration(int type, char *id) { Symbol * var; int size = SIZE(type); var = insert_global_sym(GLOB_VAR,id); if(var == NULL) { fprintf(stderr, "line %d: malloc global var error
", save_line); } var->type = type; /* var */ if(token == TOK_SEMI) { if(type == TOK_PINT || type == TOK_PCHAR) { var->u.g.is_pointer = true; } var->u.g.size = size; match(TOK_SEMI); } /* array */ else if(token == TOK_LSQUARE) { match(TOK_LSQUARE); match(TOK_NUM); match(TOK_RSQUARE); match(TOK_SEMI); var->u.g.is_array = true; var->u.g.size = save_num * size; } else fprintf(stderr, "line %d: param does not a type
", save_line); return &var->u.g; } static void params() { if(token == TOK_VOID){ match(TOK_VOID); } else if( token == TOK_INT || token == TOK_CHAR || token == TOK_PINT || token == TOK_PCHAR || token == TOK_VOID || token == TOK_PVOID){ param_list(); }else{ if(token != TOK_RPAREN) fprintf(stderr, "line %d: function params error
", save_line); } } static void param_list() { int seq = 0; do { insert_param(param(),seq,¤t_function->u.f.param_head); seq++; if(token == TOK_COMMA) match(TOK_COMMA); else break; }while(true); } static ListHead* param() { ParamInfo *param = NULL; param = malloc(sizeof(ParamInfo)); if(param == NULL) { fprintf(stderr,"param node malloc error"); exit(0); } memset(param,0,sizeof(ParamInfo)); INIT_LIST_NODE(¶m->param_list); param->type = token; param->size = SIZE(token); if(token == TOK_INT || token == TOK_CHAR|| token == TOK_PINT || token == TOK_PCHAR|| token == TOK_VOID || token == TOK_PVOID) { match(token); } strncpy(param->name,save_word,NAME_SIZE); match(TOK_ID); if(token==TOK_LSQUARE) { param->is_array = true; match(TOK_LSQUARE); match(TOK_RSQUARE); } return ¶m->param_list; } static void compound_stmt() { ListHead *t = NULL; /* match { */ match( TOK_LBRACKET ); while(token==TOK_INT||token==TOK_CHAR ||token==TOK_PINT||token==TOK_PCHAR) { t = local_var_declaration(token); insert_local_var(t,&offset,&(current_function->u.f.auto_head)); offset.current_level++; offset.current_block++; } current_function->u.f.total_offset = offset.local_total_offset; statement_list(); /* match } */ match(TOK_RBRACKET); offset.current_level--; } static ListHead* local_var_declaration(int type) { AutoInfo *a = NULL; int size = SIZE(type); a = malloc(sizeof(AutoInfo)); if(a == NULL){ fprintf(stderr, "line %d: malloc auto error
", save_line); exit(0); } memset(a, 0, sizeof(AutoInfo)); INIT_LIST_NODE(&a->auto_list); match(token); strncpy(a->name,save_word,NAME_SIZE); match(TOK_ID); a->type = type; /* var */ if(token == TOK_SEMI){ if(type == TOK_PINT || type == TOK_PCHAR) a->is_pointer = true; a->size = size; match(TOK_SEMI); } /* array */ else if(token == TOK_LSQUARE){ /* match [ */ match(TOK_LSQUARE); match(TOK_NUM); match(TOK_RSQUARE); match(TOK_SEMI); a->size = size * save_num; a->is_array = true; }else{ fprintf(stderr, "line %d: param does not a type
", save_line); } return &a->auto_list; } static void statement_list() { while(token == TOK_IF || token == TOK_LBRACKET ||token == TOK_ID || token == TOK_MUL ||token == TOK_AND || token == TOK_WHILE ||token == TOK_RETURN || token == TOK_SEMI ||token == TOK_FOR) { statement(); } } static void statement() { int second_token; if(token == TOK_IF){ selection_stmt(); }else if(token == TOK_LBRACKET){ compound_stmt(); }else if(token == TOK_ID||token == TOK_AND){ second_token = virtual_get_token(true); if(second_token == TOK_ASSIGN){ assign_stmt(); }else if(second_token == TOK_LSQUARE){ while(second_token!=TOK_RSQUARE){ second_token = virtual_get_token(false); if(second_token == TOK_ASSIGN ||second_token == TOK_SEMI ||second_token == TOK_EOF) { fprintf( stderr, "line %d: error array var", save_line ); break; } } second_token = virtual_get_token(false); if(second_token == TOK_ASSIGN){ assign_stmt(); }else{ expression_stmt(); } }else{ expression_stmt(); } }else if(token == TOK_WHILE||token == TOK_FOR){ iteration_stmt(); }else if(token == TOK_RETURN){ return_stmt(); }else if(token == TOK_SEMI){ match(TOK_SEMI); }else fprintf( stderr, "line %d: error statements", save_line ); } static void assign_stmt() { int addr; before_assign = true; var(); match(TOK_ASSIGN); before_assign = false; expression(); gen_code("sto
"); match(TOK_SEMI); } static void expression_stmt() { expression(); match(TOK_SEMI); } static void selection_stmt() { int first_label = -1; int second_label = -1; match(TOK_IF); match(TOK_LPAREN); expression(); first_label = get_label(); gen_code("fjp %d
", first_label); match(TOK_RPAREN); statement(); second_label = get_label(); gen_code("ujp %d
", second_label); gen_code("lab %d:
", first_label); if(token == TOK_ELSE){ match(TOK_ELSE); statement(); } gen_code("lab %d:
", second_label); } static void iteration_stmt() { int first_label = -1; int second_label = -1; first_label = get_label(); gen_code("lab %d:
", first_label); if(token == TOK_WHILE) { match(TOK_WHILE); match(TOK_LPAREN); /* ( */ expression(); second_label = get_label(); gen_code("fjp %d
", second_label); match(TOK_RPAREN); /* ) */ statement(); gen_code("ujp %d
", first_label); gen_code("lab %d:
", second_label); }else if(token == TOK_FOR){ match(TOK_FOR); match(TOK_LPAREN);/* ( */ expression(); match(TOK_SEMI); expression(); match(TOK_SEMI); expression(); match(TOK_RPAREN);/* ) */ second_label = get_label(); gen_code("etu %d
", second_label); statement(); gen_code("ujp %d
", first_label); gen_code("lab %d:
", second_label); } else{ } } static void return_stmt() { match(TOK_RETURN); if(token == TOK_SEMI) { gen_code("ret
"); match(TOK_SEMI); } else { expression(); gen_code("ret
"); match(TOK_SEMI); has_return_value = true; } } static void expression() { int op_token; int first_label = -1; int second_label = -1; additive_expression(); if(!(token==TOK_LE||token==TOK_LT ||token==TOK_GT||token==TOK_GE ||token==TOK_EQ||token==TOK_NE)) { return ; } while(token==TOK_LE||token==TOK_LT|| token==TOK_GT||token==TOK_GE|| token==TOK_EQ||token==TOK_NE) { op_token = token; match(token); additive_expression(); //gen_code("sbi
"); //gen_code("exc
"); //gen_code("cmp
"); first_label = get_label(); switch(op_token) { case TOK_LE: // <= gen_code("leq L%d
", first_label); break; case TOK_LT: // < gen_code("les L%d
", first_label); break; case TOK_GT: // > gen_code("grt L%d
", first_label); break; case TOK_GE: // >= gen_code("geq L%d
", first_label); break; case TOK_EQ: // == gen_code("equ L%d
", first_label); break; case TOK_NE: // != gen_code("neq L%d
", first_label); break; } second_label = get_label(); gen_code("ldc %d
", false); gen_code("ujp L%d
", second_label); gen_code("lab %d:
", first_label); gen_code("ldc %d
", true); gen_code("lab %d:
", second_label); } } static int relop() { switch(token) { case TOK_LE: match(TOK_LE); break; case TOK_LT: match(TOK_LT); break; case TOK_GT: match(TOK_GT); break; case TOK_GE: match(TOK_GE); break; case TOK_EQ: match(TOK_EQ); break; case TOK_NE: match(TOK_NE); break; } return token; } static void additive_expression() { int op_token; term(); while(token == TOK_PLUS || token == TOK_MINUS) { op_token = token; match(token); term(); if(op_token == TOK_PLUS){ gen_code("adi
"); }else if(op_token == TOK_MINUS){ gen_code("sbi
"); } else{ //common_error } } } static void term() { int op_token; factor(); while(token == TOK_MUL||token == TOK_DIV) { op_token = token; match(token); factor(); if(op_token == TOK_MUL){ gen_code("mpi
"); }else if(op_token == TOK_DIV){ gen_code("dvi
"); }else{ //common_error } } } static void factor() { int next_token; if(token == TOK_LPAREN){ match(TOK_LPAREN); expression(); //does not support (x=x+3)+4 match(TOK_RPAREN); }else if(token==TOK_ID||token == TOK_AND){ next_token = virtual_get_token(true); if(next_token == TOK_LPAREN){ call(); }else{ var(); } } else if(token == TOK_NUM){ gen_code("ldc %d
", save_num); match(TOK_NUM); }else if(token == TOK_PLUS||token == TOK_MINUS) { /* 0 + a -> +a 0 - a -> -a */ //first element is zero } else fprintf(stderr, "line %d: unexpected factor %s
", save_line, save_word); } static void var() { int has_prefix = false; int var_addr; AutoInfo * _auto = NULL; ParamInfo * _param = NULL; Symbol * _global = NULL; //Symbol * temp = NULL; if(token==TOK_MUL||token==TOK_AND){ has_prefix = true; /* if is * or & */ match(token); // } _global = lookup_global_sym(GLOB_VAR,save_word); _auto = lookup_local_var(save_word); _param = lookup_param(save_word); match(TOK_ID); /* array */ if(token == TOK_LSQUARE){ if(_auto && _param){ fprintf(stderr, "line %d: param and auto can't be same name
", save_line); } if(_param){ gen_code("lda %d
", _param->offset); }else if(_auto){ gen_code("lda %d
", _auto->offset); }else if(_global){ gen_code("lda %d
", _global->u.g.offset); }else{ fprintf(stderr, "line %d: can't find var %s
", save_line, save_word); } match(TOK_LSQUARE); var_in_square = true; expression(); var_in_square = false; match(TOK_RSQUARE); gen_code("ixa elem_size(%d)
", 4); if(!before_assign){ gen_code("ind %d
",0); } } /* not array */ else { if(_auto && _param){ fprintf(stderr, "line %d: param and auto can't be same name
", save_line); } if(_param){ var_addr = _param->offset; }else if(_auto){ var_addr = _auto->offset; }else if(_global){ var_addr = _global->u.g.offset; }else{ fprintf(stderr, "line %d: can't find var %s
", save_line, save_word); } if((before_assign && !var_in_square) || var_in_read_write){ gen_code("lda %d
", var_addr); }else{ gen_code("lod %d
", var_addr); } } } static void call() { char func_name[NAME_SIZE]; Symbol *f; strcpy(func_name,save_word); match(TOK_ID); f = lookup_global_sym(FUNCTION,func_name); if(!f){ fprintf(stderr,"can not call func %s", func_name); } if(strcmp(save_word,"read") && strcmp(save_word,"write")){ gen_code("mst %d
", f->u.f.total_offset*10000 + f->u.f.param_size); }else{ var_in_read_write = true; } match(TOK_LPAREN); args(); match(TOK_RPAREN); var_in_read_write = false; gen_code("cal %d
",f->u.f.id); } static void args() { if(token == TOK_ID||token == TOK_NUM) { expression(); while(token == TOK_COMMA) { match(TOK_COMMA); expression(); } } }

좋은 웹페이지 즐겨찾기