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

📄 c.y

📁 C编译器,在VC6.0环境下开发
💻 Y
📖 第 1 页 / 共 5 页
字号:
				$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 oMODASSIGN assignment_expression
			{
				PARSE_INFO("assignment_expression :unary_expression oMODASSIGN assignment_expression")
				if ( !IS_LVALUE($1) )
				{
					yyerror("'%=' : left operand must be l-value");
					user_exit(1);
				}
				CHECK_BIT_OP_TYPE($1)
				CHECK_BIT_OP_TYPE($3)
				// 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, dx
				gen_mov_reg_to_var("dx", $1);
				del_symbol($3);
				// set rvalue flag
				$1->is_rvalue = 1;
				if ( IS_ARRAY($1) )
				{
					// push dx
					gen_push_reg("dx");
					// set pushed flag
					$1->is_pushed = 1;
				}
				// not push, so not set pushed flag
			}
		|	unary_expression oBITORASSIGN assignment_expression
			{
				PARSE_INFO("assignment_expression :unary_expression oBITORASSIGN assignment_expression")
				if ( !IS_LVALUE($1) )
				{
					yyerror("'|=' : left operand must be l-value");
					user_exit(1);
				}
				CHECK_BIT_OP_TYPE($1)
				CHECK_BIT_OP_TYPE($3)
				// mov	ax, $3
				gen_mov_value_to_reg($3, "ax");
				if ( IS_ARRAY($1) )
					gen_get_array_element($1);
				// or	ax,	$1
				gen_or("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 oBITANDASSIGN assignment_expression
			{
				PARSE_INFO("assignment_expression :unary_expression oBITANDASSIGN assignment_expression")
				if ( !IS_LVALUE($1) )
				{
					yyerror("'&=' : left operand must be l-value");
					user_exit(1);
				}
				CHECK_BIT_OP_TYPE($1)
				CHECK_BIT_OP_TYPE($3)
				// mov	ax, $3
				gen_mov_value_to_reg($3, "ax");
				if ( IS_ARRAY($1) )
					gen_get_array_element($1);
				// and	ax,	$1
				gen_and("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 oBITXORASSIGN assignment_expression
			{
				PARSE_INFO("assignment_expression :unary_expression oBITXORASSIGN assignment_expression")
				if ( !IS_LVALUE($1) )
				{
					yyerror("'^=' : left operand must be l-value");
					user_exit(1);
				}
				CHECK_BIT_OP_TYPE($1)
				CHECK_BIT_OP_TYPE($3)
				// mov	ax, $3
				gen_mov_value_to_reg($3, "ax");
				if ( IS_ARRAY($1) )
					gen_get_array_element($1);
				// xor	ax,	$1
				gen_xor("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 oLFTSHTASSIGN assignment_expression
			{
				PARSE_INFO("assignment_expression :unary_expression oLFTSHTASSIGN assignment_expression")
				if ( !IS_LVALUE($1) )
				{
					yyerror("'<<=' : left operand must be l-value");
					user_exit(1);
				}
				CHECK_BIT_OP_TYPE($1)
				CHECK_BIT_OP_TYPE($3)
				// mov	cx, $3
				gen_mov_value_to_reg($3, "cx");
				if ( IS_ARRAY($1) )
					gen_get_array_element($1);
				// shl	$1, cl
				gen_shl($1->rname, "cl");
				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 oRITSHTASSIGN assignment_expression
			{
				PARSE_INFO("assignment_expression :unary_expression oRITSHTASSIGN assignment_expression")
				if ( !IS_LVALUE($1) )
				{
					yyerror("'>>=' : left operand must be l-value");
					user_exit(1);
				}
				CHECK_BIT_OP_TYPE($1)
				CHECK_BIT_OP_TYPE($3)
				// mov	cx, $3
				gen_mov_value_to_reg($3, "cx");
				if ( IS_ARRAY($1) )
					gen_get_array_element($1);
				// shr	$1, cl
				gen_shr($1->rname, "cl");
				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
			}
		;

/*
assignment_operator
		:	oASSIGN
			{
				PARSE_INFO("assignment_operator :oASSIGN")
			}
		|	oPLUSASSIGN
			{
				PARSE_INFO("assignment_operator :oPLUSASSIGN")
			}
		|	oMINUSASSIGN
			{
				PARSE_INFO("assignment_operator :oMINUSASSIGN")
			}
		|	oMULASSIGN
			{
				PARSE_INFO("assignment_operator :oMULASSIGN")
			}
		|	oDIVASSIGN
			{
				PARSE_INFO("assignment_operator :oDIVASSIGN")
			}
		|	oMODASSIGN
			{
				PARSE_INFO("assignment_operator :oMODASSIGN")
			}
		|	oBITORASSIGN
			{
				PARSE_INFO("assignment_operator :oBITORASSIGN")
			}
		|	oBITANDASSIGN
			{
				PARSE_INFO("assignment_operator :oBITANDASSIGN")
			}
		|	oBITXORASSIGN
			{
				PARSE_INFO("assignment_operator :oBITXORASSIGN")
			}
		;
*/
			
conditional_expression
		:	logical_OR_expression
			{
				PARSE_INFO("conditional_expression :logical_OR_expression")
			}
		|	logical_OR_expression oQUESTION expression oCOLON conditional_expression
			{
				symbol	*p;

				PARSE_INFO("conditional_expression :logical_OR_expression oQUESTION expression oCOLON conditional_expression")
				if ( !$3 )
				{
					yyerror("empty between '?' and ':'");
					user_exit(1);
				}
				if ( IS_CL($1) && IS_CL($3) && IS_CL($5) )
				{
					cast_cl_type($1, $3);
					cast_cl_type($3, $5);
					cast_cl_type($1, $5);

					switch($1->NOUN)
					{
					case	SPEC_CHAR:
						$1->V_C = ($1->V_C ? $3->V_C : $5->V_C);
						break;
					case	SPEC_INT:
						$1->V_I = ($1->V_I ? $3->V_I : $5->V_I);
						break;
					case	SPEC_DOUBLE:
						$1->V_LF = ($1->V_LF ? $3->V_LF : $5->V_LF);
						break;
					case	SPEC_FLOAT:
						$1->V_F = ($1->V_F ? $3->V_F : $5->V_F);
						break;
					default:
						yyerror("can't do cl operator");
						user_exit(1);
					}
					del_symbol($3);
					del_symbol($5);
					p = $1;
				}
				else
				{
					char	lab1[LABEL_LEN], lab2[LABEL_LEN];

					strcpy(lab1, get_a_label());
					strcpy(lab2, get_a_label());
					// at least one is not cl

					gen_mov_value_to_reg($5, "dx");
					gen_mov_value_to_reg($3, "ax");
					gen_mov_value_to_reg($1, "bx");

					/*  bx ? ax : dx */
					//	or	bx,	bx
					gen_or("bx", "bx");
					//	jnz	lab1
					gen_jump("jnz", lab1);
					//	push	dx
					gen_push_reg("dx");
					//	jmp	lab2
					gen_jump("jmp", lab2);
					//lab1:
					gen_label(lab1);
					//	push	ax
					gen_push_reg("ax");
					//lab2:
					gen_label(lab2);

					if ( !IS_CL($1) )
					{
						del_symbol($3);
						del_symbol($5);
						p  = $1;
					}
					if ( !IS_CL($3) )
					{
						del_symbol($1);
						del_symbol($5);
						p  = $3;
					}
					del_symbol($1);
					del_symbol($3);
					p  = $5;

					// set rvalue flag
					p->is_rvalue = 1;
					// set pused flag
					p->is_pushed = 1;
				}
				$$ = p;
			}
		;

constant_expression
		:	conditional_expression
			{
				PARSE_INFO("constant_expression :conditional_expression")
			}
		;

logical_OR_expression
		:	logical_AND_expression
			{
				PARSE_INFO("logical_OR_expression :logical_AND_expression")
			}
		|	logical_OR_expression oOR logical_AND_expression
			{
				symbol	*p;

				PARSE_INFO("logical_OR_expression :logical_OR_expression oOR logical_AND_expression")
				if ( IS_CL($1) && IS_CL($3) )
				{
					cast_cl_type($1, $3);
					_CL_DOUBLE_OPERATION($1, $3, ||)
					del_symbol($3);
					p = $1;
				}
				else
				{
					char	lab1[LABEL_LEN], lab2[LABEL_LEN];

					strcpy(lab1, get_a_label());
					strcpy(lab2, get_a_label());
					p = gen_get_two_op_not_cl($1, $3, "ax", "dx");

					//	or	ax,	ax
					gen_or("ax", "ax");
					// jnz	lab1
					gen_jump("jnz", lab1);
					//	or	dx,	dx
					gen_or("dx", "dx");
					//	jnz	lab1
					gen_jump("jnz", lab1);
					//	xor	ax,	ax
					gen_xor("ax", "ax");
					// jmp lab2
					gen_jump("jmp", lab2);
					// lab1:
					gen_label(lab1);
					// mov	ax,	1
					gen_mov_cl("ax", 1);
					// lab2:
					gen_label(lab2);
					// push	ax
					gen_push_reg("ax");
					
					// set rvalue flag
					p->is_rvalue = 1;
					// set pused flag
					p->is_pushed = 1;
				}
				$$ = p;
			}
		;

logical_AND_expression
		:	inclusive_OR_expression
			{
				PARSE_INFO("logical_AND_expression :inclusive_OR_expression")
			}
		|	logical_AND_expression oAND inclusive_OR_expression
			{
				symbol	*p;

				PARSE_INFO("logical_AND_expression :logical_AND_expression oAND inclusive_OR_expression")
				if ( IS_CL($1) && IS_CL($3) )
				{
					cast_cl_type($1, $3);
					_CL_DOUBLE_OPERATION($1, $3, &&)
					del_symbol($3);
					p = $1;
				}
				else
				{
					char	lab1[LABEL_LEN], lab2[LABEL_LEN];

					strcpy(lab1, get_a_label());
					strcpy(lab2, get_a_label());
					p = gen_get_two_op_not_cl($1, $3, "ax", "dx");

					//	or	ax,	ax
					gen_or("ax", "ax");
					// jz	lab1
					gen_jump("jz", lab1);
					//	or	dx,	dx
					gen_or("dx", "dx");
					//	jz	lab1
					gen_jump("jz", lab1);
					//	mov	ax,	1
					gen_mov_cl("ax", 1);
					// jmp lab2
					gen_jump("jmp", lab2);
					// lab1:
					gen_label(lab1);
					// xor	ax, ax
					gen_xor("ax", "ax");
					// lab2:
					gen_label(lab2);
					// push	ax
					gen_push_reg("ax");
					
					// set rvalue flag
					p->is_rvalue = 1;
					// set pused flag
					p->is_pushed = 1;
				}
				$$ = p;
			}
		;

inclusive_OR_expression
		:	exclusive_OR_expression
			{
				PARSE_INFO("inclusive_OR_expression :exclusive_OR_expression")
			}
		|	inclusive_OR_expression oBITOR exclusive_OR_expression
			{
				symbol	*p;

				PARSE_INFO("inclusive_OR_expression :inclusive_OR_expression oBITOR exclusive_OR_expression")
				CHECK_BIT_OP_TYPE($1)
				CHECK_BIT_OP_TYPE($3)
				if ( IS_CL($1) && IS_CL($3) )
				{
					cast_cl_type($1, $3);
					_CL_DOUBLE_BIT_OPERATION($1, $3, |)
					del_symbol($3);
					p = $1;
				}
				else
				{
					p = gen_get_two_op_not_cl($1, $3, "ax", "dx");

					// or ax, dx
					gen_or("ax", "dx");
					// push	ax
					gen_push_reg("ax");
					
					// set rvalue flag
					p->is_rvalue = 1;
					// set pused flag
					p->is_pushed = 1;
				}
				$$ = p;
			}
		;

exclusive_OR_expression
		:	AND_expression
			{
				PARSE_INFO("exclusive_OR_expression :AND_expression")
			}
		|	exclusive_OR_expression oBITXOR AND_expression
			{
				symbol	*p;

				PARSE_INFO("exclusive_OR_expression :exclusive_OR_expression oBITXOR AND_expression")
				CHECK_BIT_OP_TYPE($1)
				CHECK_BIT_OP_TYPE($3)
				if ( IS_CL($1) && IS_CL($3) )
				{
					cast_cl_type($1, $3);
					_CL_DOUBLE_BIT_OPERATION($1, $3, ^)
					del_symbol($3);
					p = $1;
				}
				else
				{
					p = gen_get_two_op_not_cl($1, $3, "ax", "dx");

					// xor ax, dx
					gen_xor("ax", "dx");
					// push	ax
					gen_push_reg("ax");
					
					// set rvalue flag
					p->is_rvalue = 1;
					// set pused flag
					p->is_pushed = 1;
				}
				$$ = p;
			}
		;

AND_expression
		:	equality_expression
			{
				PARSE_INFO("AND_expression :equality_expression")
			}
		|	AND_expression oBITAND equality_expression
			{
				symbol	*p;

				PARSE_INFO("AND_expression :AND_expression oBITAND equality_expression")
				CHECK_BIT_OP_TYPE($1)
				CHECK_BIT_OP_TYPE($3)
				if ( IS_CL($1) && IS_CL($3) )
				{
					cast_cl_type($1, $3);
					_CL_DOUBLE_BIT_OPERATION($1, $3, &)
					del_symbol($3);
					p = $1;
				}
				else
				{
					p = gen_get_two_op_not_cl($1, $3, "ax", "dx");

					// and ax, dx
					gen_and("ax", "dx");
					// push	ax
					gen_push_reg("ax");
					
					// set rvalue flag
					p->is_rvalue = 1;
					// set pused flag
					p->is_pushed = 1;
				}
				$$ = p;
			}
		;

equality_expression
		:	relational_expression
			{
				PARSE_INFO("equality_expression :relational_expression")
			}
		|	equality_expression oEQUAL relational_expression
			{
				symbol	*p;

				PARSE_INFO("equality_expression :equality_expression oEQUAL relational_expression")
				if ( IS_CL($1) && IS_CL($3) )
				{
					// calcu it
					cast_cl_type($1, $3);
					_CL_DOUBLE_OPERATION($1, $3, ==)
					del_symbol($3);
					p = $1;
				}
				else
				{
					char	lab1[LABEL_LEN], lab2[LABEL_LEN];

					strcpy(lab1, get_a_label());
					strcpy(lab2, get_a_label());
					p = gen_get_two_op_not_cl($1, $3, "ax", "dx");

⌨️ 快捷键说明

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