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

📄 spl.y.c

📁 浙江大学编译原理课程设计源代码,高等院校计算机专业
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef GENERATE_AST	{		list_clear(&dag_forest);		t = new_tree(TAIL, NULL, NULL, NULL);		list_append(&ast_forest, t);		/* generate dag forest. */		gen_dag(&ast_forest, &dag_forest);		/* emit asm code. */		emit_code(&dag_forest);	}#else	emit_routine_epilogue(top_symtab_stack());#endif	pop_symtab_stack();};procedure_head:kPROCEDURE{#ifdef GENERATE_AST	list_clear(&ast_forest);	list_clear(&para_list);#endif	ptab = new_symtab(top_symtab_stack());	push_symtab_stack(ptab);}yNAME parameters{	ptab = top_symtab_stack();	strncpy(ptab->name, $3, NAME_LEN);	sprintf(ptab->rname, "rtn%03d",ptab->id);	ptab->defn = DEF_PROC;	p = new_symbol($3, DEF_PROC, TYPE_VOID);	add_symbol_to_table(ptab,p);	reverse_parameters(ptab);#ifdef GENERATE_AST	{		Tree header;				header = new_tree(HEADER, find_type_by_id(TYPE_VOID), NULL, NULL);		header->u.header.para = &para_list;		list_append(&ast_forest, header);		now_function = new_tree(ROUTINE, find_type_by_id(TYPE_VOID), header, NULL);	}#endif	};parameters:oLP para_decl_list oRP{	ptab = top_symtab_stack();	ptab->local_size = 0;}|;para_decl_list:para_decl_list oSEMI para_type_list|para_type_list;para_type_list: val_para_list oCOLON simple_type_decl{	ptab = top_symtab_stack();	for(p = $1; p ;){		if($3->type_id			== TYPE_SUBRANGE)			p->type = $3->first->type;		else if ($3->type_id == TYPE_ENUM)			p->type = find_type_by_id(TYPE_INTEGER);		else			p->type = find_type_by_id($3->type_id);		p->type_link = $3;		p->defn = DEF_VALPARA;		q = p; p = p->next;		q->next = NULL;		add_symbol_to_table(ptab,q);#ifdef GENERATE_AST		/* append to paralist. */		list_append(&para_list, q);#endif	}	$1 = NULL;}| var_para_list oCOLON simple_type_decl{	ptab = top_symtab_stack();	for(p = $1; p;){		if($3->type_id == TYPE_SUBRANGE)			p->type = $3->first->type;		else if($3->type_id == TYPE_ENUM)			p->type = find_type_by_id(TYPE_INTEGER);		else			p->type = find_type_by_id($3->type_id);		p->type_link = $3;		p->defn = DEF_VARPARA;		q = p; p = p->next;		q->next=NULL;		add_symbol_to_table(ptab,q);#ifdef GENERATE_AST		/* append to para_list. */		list_append(&para_list, q);#endif	}	$1 = NULL;};val_para_list:name_list;var_para_list:kVAR name_list{	$$ = $2;};routine_body:compound_stmt;stmt_list:stmt_list stmt oSEMI|stmt_list error oSEMI|;stmt:cINTEGER oCOLON non_label_stmt| non_label_stmt;non_label_stmt:assign_stmt| proc_stmt| compound_stmt| if_stmt| repeat_stmt| while_stmt| for_stmt| case_stmt| goto_stmt|;assign_stmt:yNAME oASSIGN expression{	p = find_symbol(top_symtab_stack(), $1);	if (p == NULL)	{		parse_error("Undefined identifier", $1);		p = install_temporary_symbol($1, DEF_VAR, TYPE_INTEGER);	}	if(p->type->type_id == TYPE_ARRAY		||p->type->type_id == TYPE_RECORD)	{		parse_error("lvalue expected","");		/* return 0; */	}	if (p && p->defn != DEF_FUNCT)	{	#ifdef GENERATE_AST		if(p->type->type_id != $3->result_type->type_id)	#else		if(p->type->type_id != $3)	#endif		{			parse_error("type mismatch","");			/* return 0; */		}	}	else	{		ptab = find_routine($1);		if(ptab)		{		#ifdef GENERATE_AST			if(ptab->type->type_id != $3->result_type->type_id)		#else			if(ptab->type->type_id != $3)		#endif			{				parse_error("type mismatch","");				/* return 0; */			}		}		else{			parse_error("Undeclared identifier.",$1);		#ifdef GENERATE_AST			install_temporary_symbol($1, DEF_VAR, $3->result_type->type_id);		#else			install_temporary_symbol($1, DEF_VAR, $3);		#endif			/* return 0; */		}	}#ifdef GENERATE_AST	t = address_tree(NULL, p);	$$ = assign_tree(t, $3);		/* append to forest. */	list_append(&ast_forest, $$);	#else		if (p && p->defn != DEF_FUNCT)	{		do_assign(p, $3);	}	else	{		do_function_assign(ptab, $3);	}#endif}|yNAME oLB{	p = find_symbol(top_symtab_stack(), $1);	if(!p || p->type->type_id != TYPE_ARRAY){		parse_error("Undeclared array name",$1);		return 0;	}		push_term_stack(p);#ifdef GENERATE_AST#else	emit_load_address(p);	emit_push_op(TYPE_INTEGER);#endif}expression oRB{	p = top_term_stack();#ifdef GENERATE_AST	p = find_symbol(top_symtab_stack(), $1);	if(!p || p->type->type_id != TYPE_ARRAY){		parse_error("Undeclared array name",$1);		return 0;	}		t = array_factor_tree(p, $4);	t = address_tree(t, p);	push_ast_stack(t);#else	do_array_factor(p);#endif}oASSIGN expression{#ifdef GENERATE_AST	t = pop_ast_stack();	$$ = assign_tree(t, $8);	list_append(&ast_forest, $$);#else	p = pop_term_stack();	do_assign(p, $8);#endif}|yNAME oDOT yNAME{	p = find_symbol(top_symtab_stack(),$1);	if(!p || p->type->type_id != TYPE_RECORD){		parse_error("Undeclared record vaiable",$1);		return 0;	}	q = find_field(p,$3);	if(!q || q->defn != DEF_FIELD){		parse_error("Undeclared field",$3);		return 0;	}#ifdef GENERATE_AST	t = field_tree(p, q);	t = address_tree(t, q);	push_ast_stack(t);#else	emit_load_address(p);	emit_push_op(TYPE_INTEGER);	do_record_factor(p,q);	push_term_stack(p);	push_term_stack(q);#endif}oASSIGN expression{#ifdef GENERATE_AST	t = pop_ast_stack();	$$ = assign_tree(t, $6);	list_append(&ast_forest, $$);#else	q = pop_term_stack();	p = pop_term_stack();	do_assign(q, $6);#endif};proc_stmt:yNAME{	ptab = find_routine($1);	if(!ptab || ptab->defn != DEF_PROC){		parse_error("Undeclared procedure",$1);		return 0;	}#ifdef GENERATE_AST	$$ = call_tree(ptab, NULL);	list_append(&ast_forest, $$);#else	do_procedure_call(ptab);#endif}|yNAME{	ptab = find_routine($1);	if(!ptab || ptab->defn != DEF_PROC){			parse_error("Undeclared procedure",$1);			return 0;	}	push_call_stack(ptab);}oLP args_list oRP{#ifdef GENERATE_AST	$$ = call_tree(top_call_stack(), args);	list_append(&ast_forest, $$);#else	do_procedure_call(top_call_stack());#endif	pop_call_stack();}|SYS_PROC{#ifdef GENERATE_AST	$$ = sys_tree($1->attr, NULL);	list_append(&ast_forest, $$);#else	do_sys_routine($1->attr, 0);#endif}|SYS_PROC {	rtn = find_sys_routine($1->attr);	if(rtn)		arg = rtn->args;	else	{		arg = NULL;	}	push_call_stack(rtn);}oLP expression_list oRP {#ifdef GENERATE_AST	$$ = sys_tree($1->attr, $4);	list_append(&ast_forest, $$);#else	do_sys_routine($1->attr, $4);#endif		pop_call_stack();}|pREAD oLP factor oRP{	if(!$3){		parse_error("too few parameters in call to", "read");		return 0;	}#ifdef GENERATE_AST	if (generic($3->op) == LOAD)		t = address_tree(NULL, $3->u.generic.sym);	else		t = address_tree($3, $3->u.generic.sym);	$$ = sys_tree(pREAD, t);	list_append(&ast_forest, $$);#else	emit_load_address($3);	do_sys_routine(pREAD, $3->type->type_id);#endif};compound_stmt:kBEGIN{#ifdef GENERATE_AST	/* block begin. */	t = new_tree(BLOCKBEG, NULL, NULL, NULL);	list_append(&ast_forest, t);#endif}stmt_listkEND{#ifdef GENERATE_AST	/* block end. */	t = new_tree(BLOCKEND, NULL, NULL, NULL);	list_append(&ast_forest, t);#endif};if_stmt:kIF {#ifdef GENERATE_AST	push_lbl_stack(if_label_count++);#endif}expression kTHEN{#ifdef GENERATE_AST	snprintf(mini_buf, sizeof(mini_buf) - 1, "if_false_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	new_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = cond_jump_tree($3, false, new_label);	list_append(&ast_forest, t);#else	do_if_test();#endif}stmt{#ifdef GENERATE_AST	snprintf(mini_buf, sizeof(mini_buf) - 1, "if_false_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	new_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = label_tree(new_label);	push_ast_stack(t);	snprintf(mini_buf, sizeof(mini_buf) - 1, "if_exit_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	exit_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	/* append jump tree. */	t = jump_tree(exit_label);	list_append(&ast_forest, t);		/* append label tree. */	t = pop_ast_stack();	list_append(&ast_forest, t);#else	do_if_clause();#endif}else_clause{#ifdef GENERATE_AST	/* append exit label. */	snprintf(mini_buf, sizeof(mini_buf) - 1, "if_exit_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	exit_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = label_tree(exit_label);	list_append(&ast_forest, t);	pop_lbl_stack();#else	do_if_exit();#endif}|kIF error {	printf("expression expected.\n");}kTHEN {	printf("then matched.\n");}stmt else_clause;else_clause:kELSE stmt|;repeat_stmt:kREPEAT{#ifdef GENERATE_AST	push_lbl_stack(repeat_label_count++);	snprintf(mini_buf, sizeof(mini_buf) - 1, "repeat_%d", repeat_label_count - 1);	mini_buf[sizeof(mini_buf) - 1] = 0;	new_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = label_tree(new_label);	list_append(&ast_forest, t);#else	do_repeat_start();#endif}stmt_list kUNTIL expression{#ifdef GENERATE_AST	snprintf(mini_buf, sizeof(mini_buf) - 1, "repeat_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	new_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = cond_jump_tree($5, false, new_label);	list_append(&ast_forest, t);	pop_lbl_stack();#else	do_repeat_exit();#endif};while_stmt:kWHILE{#ifdef GENERATE_AST	push_lbl_stack(while_label_count++);	snprintf(mini_buf, sizeof(mini_buf) - 1, "while_test_%d", while_label_count - 1);	mini_buf[sizeof(mini_buf) - 1] = 0;	test_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = label_tree(test_label);	list_append(&ast_forest, t);#else	do_while_start();#endif}expression kDO{#ifdef GENERATE_AST	snprintf(mini_buf, sizeof(mini_buf) - 1, "while_exit_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	exit_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = cond_jump_tree($3, false, exit_label);	list_append(&ast_forest, t);#else	do_while_expr();#endif}stmt{#ifdef GENERATE_AST	/* generate while_exit_%d label tree and push. */	snprintf(mini_buf, sizeof(mini_buf) - 1, "while_exit_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	exit_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = label_tree(exit_label);	push_ast_stack(t);	snprintf(mini_buf, sizeof(mini_buf) - 1, "while_test_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	test_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	/* jump to test tree. */	t = jump_tree(test_label);	list_append(&ast_forest, t);	/* pop while_exit_%d label tree and append. */	t = pop_ast_stack();	list_append(&ast_forest, t);	pop_lbl_stack();#else	do_while_exit();#endif};for_stmt:kFOR yNAME oASSIGN expression{	p = find_symbol(top_symtab_stack(),$2);	if(!p || p->defn != DEF_VAR)	{		parse_error("lvalue expected","");		return 0;	}	if(p->type->type_id == TYPE_ARRAY		||p->type->type_id == TYPE_RECORD)	{		parse_error("lvalue expected","");		return 0;	}#ifdef GENERATE_AST		/* assign tree */	t = address_tree(NULL, p);	push_ast_stack(t);	list_append(&ast_forest, assign_tree(t, $4));	/* label tree. */	push_lbl_stack(for_label_count++);	snprintf(mini_buf, sizeof(mini_buf) - 1, "for_test_%d", for_label_count - 1);	mini_buf[sizeof(mini_buf) - 1] = 0;	test_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = label_tree(test_label);	list_append(&ast_forest, t);#else	do_for_start(p);#endif}direction expression kDO{#ifdef GENERATE_AST	snprintf(mini_buf, sizeof(mini_buf) - 1, "for_exit_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	exit_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	p = find_symbol(top_symtab_stack(),$2);	t = id_factor_tree(NULL, p);	if ($6 == kTO)	{		t = compare_expr_tree(LE, t, $7);	}	else	{		t = compare_expr_tree(GE, t, $7);	}	t = cond_jump_tree(t, false, exit_label);	list_append(&ast_forest, t);#else	do_for_test($6);#endif}stmt{#ifdef GENERATE_AST	t = pop_ast_stack();	if ($6 == kTO)	{		t = incr_one_tree(t);	}	else	{		t = decr_one_tree(t);	}	list_append(&ast_forest, t);	/* jump ast. */	snprintf(mini_buf, sizeof(mini_buf) - 1, "for_test_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	test_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = jump_tree(test_label);	list_append(&ast_forest, t);	/* add label ast. */	snprintf(mini_buf, sizeof(mini_buf) - 1, "for_exit_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	exit_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = label_tree(exit_label);	list_append(&ast_forest, t);	pop_lbl_stack();#else	do_for_exit();#endif};direction:kTO{	$$ = kTO;}|kDOWNTO{	$$ = kDOWNTO;};case_stmt:kCASE {#ifdef GENERATE_AST	push_lbl_stack(switch_label_count++);	snprintf(mini_buf, sizeof(mini_buf) - 1, "switch_test_%d", switch_label_count - 1);	mini_buf[sizeof(mini_buf) - 1] = 0;	test_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	case_label_count = 0;	t = jump_tree(test_label);	list_append(&ast_forest, t);	NEW0(case_list, STMT);	push_case_ast_stack(case_list);	case_label_count = 0;	push_case_stack(case_label_count++);	/* list_clear(&case_list); */#endif}expression kOF{#ifdef GENERATE_AST#else	do_case_start();#endif}case_expr_list{#ifdef GENERATE_AST	snprintf(mini_buf, sizeof(mini_buf) - 1, "switch_test_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	test_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = label_tree(test_label);	list_append(&ast_forest, t);	case_list = pop_case_ast_stack();	{		int n = list_length(case_list);		Tree *cases = (Tree *)list_ltov(case_list, PERM);		int i;		for (i = 0; i < n; i += 2)		{			new_label = cases[i]->u.label.label;						t = compare_expr_tree(EQ, $3, cases[i + 1]);			t = cond_jump_tree(t, true, new_label);			list_append(&ast_forest, t);		}	}	snprintf(mini_buf, sizeof(mini_buf) - 1, "switch_exit_%d", top_lbl_stack());	mini_buf[sizeof(mini_buf) - 1] = 0;	exit_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);		t = label_tree(exit_label);	list_append(&ast_forest, t);	pop_lbl_stack();#else	do_case_test();#endif}kEND;case_expr_list:case_expr_list case_expr|case_expr;case_expr:const_value{#ifdef GENERATE_AST		case_label_count = pop_case_stack();	snprintf(mini_buf, sizeof(mini_buf) - 1, "case_%d_%d", top_lbl_stack(), case_label_count++);	mini_buf[sizeof(mini_buf) - 1] = 0;	push_case_stack(case_label_count);	new_label = new_symbol(mini_buf, DEF_LABEL, TYPE_VOID);	t = label_tree(new_label);	list_append(&ast_forest, t);	case_list = top_case_ast_stack();	list_append(case_list, t);	t = const_tree($1);	list_append(case_list, t);#else	add_case_const($1);#endif}oCOLON stmt{#ifdef GENERATE_AST

⌨️ 快捷键说明

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