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

📄 semantics.cpp

📁 编译原理的三个子模块,包括词法分析,语法分析和语义分析,是绘图语言解释器
💻 CPP
字号:
// ----------------------------- semantics.cpp ---------------------------------
// 函数绘图类的定义

#include "semantics.h"

// ------------------------ 出错处理
void semantics_class::Errmsg (char *string) { exit (1); }
void semantics_class::error_msg(int line, char * descrip, char * string)
{
	const int buf_len=256;
	char msg[buf_len];

	memset(msg, 0, buf_len);
	sprintf(msg, "Line No %3d:  %s %s !", Scanner.line_no, descrip, string);
	MessageBox(NULL, msg, "error!", MB_OK);
	Scanner.close_scanner();
	exit(1);
}

// ------------------------ 计算被绘制点的坐标
void semantics_class::cal_coord(tree_node_ptr x_ptr,
								tree_node_ptr y_ptr,
								double &x_ret,
								double &y_ret)
{	
	double x_val, x_temp, y_val;

	// 计算表达式的值,得到点的原始坐标
	x_val = get_tree_value(x_ptr);
	y_val = get_tree_value(y_ptr);

	// 比例变换
	x_val *= Scale_x ;
	y_val *= Scale_y ;

	// 旋转变换
	x_temp = x_val*cos(rot_angle) + y_val*sin(rot_angle);
	y_val  = y_val*cos(rot_angle) - x_val*sin(rot_angle);
	x_val  = x_temp;
	
	// 平移变换
	x_val += Origin_x;
	y_val += Origin_y;

	// 返回变换后点的坐标
	x_ret = x_val;
	y_ret = y_val;
}

// ------------------------ 循环绘制点坐标
void semantics_class::draw_loop
			(	double start_val,
				double end_val,
				double step_val,
				tree_node_ptr x_ptr,
				tree_node_ptr y_ptr)
{
	double x_val, y_val;
	for(parameter = start_val; parameter <= end_val; parameter += step_val)
	{	cal_coord(x_ptr, y_ptr, x_val, y_val);
//		y_val = 460-y_val;			// 修改显示屏的直角坐标系
		draw_pixel((unsigned long)x_val, (unsigned long)y_val);
	}
}

// ------------------------ 计算表达式的值
double semantics_class::get_tree_value(tree_node_ptr root)
{	
	if (root == NULL) return 0.0;
	switch (root -> op_code)
	{	case PLUS  :
			return get_tree_value(root->content.tag_op.left ) +
						get_tree_value(root->content.tag_op.right) ;
		case MINUS :
			return get_tree_value(root->content.tag_op.left ) -
						get_tree_value(root->content.tag_op.right) ;
		case MUL   :
			return get_tree_value(root->content.tag_op.left ) *
						get_tree_value(root->content.tag_op.right) ;
		case DIV   :
			return get_tree_value(root->content.tag_op.left ) /
						get_tree_value(root->content.tag_op.right) ;
		case POWER :
			return pow(get_tree_value(root->content.tag_op.left ),
						get_tree_value(root->content.tag_op.right) );
		case FUNC  :
			return (* root->content.tag_func.math_func_ptr)
						(get_tree_value(root->content.tag_func.child) );
		case CONST_ID :
			return root->content.tag_const ;
		case T  :
			return *(root->content.tag_parameter);
		default    :
			return 0.0 ;
	}
}

// ------------------------ 删除一棵语法树
void semantics_class::delete_tree(tree_node_ptr root)
{	
	if (root == NULL) return;
	switch (root -> op_code)
	{   case PLUS  :			// 两个孩子的内部节点
	    case MINUS :
	    case MUL   :
	    case DIV   :
	    case POWER :
			delete_tree (root->content.tag_op.left ) ;
			delete_tree (root->content.tag_op.right) ;
			break ;
	    case FUNC  : 			// 一个孩子的内部节点
			delete_tree (root->content.tag_func.child) ;
			break ;
	    default    : 			// 叶子节点
			break ;
	}
	delete(root) ;				// 删除节点
}

// ------------------------ 绘制一个点
void semantics_class::draw_pixel(unsigned long x, unsigned long y)
{
	if (line_color==red_color) {
		SetPixel(hDC, x, y, red());
		SetPixel(hDC, x+1, y, red());
		SetPixel(hDC, x, y+1, red());
		SetPixel(hDC, x+1, y+1, red());
	}
	else {
		SetPixel(hDC, x, y, black());
		SetPixel(hDC, x+1, y, black());
		SetPixel(hDC, x, y+1, black());
		SetPixel(hDC, x+1, y+1, black());
	}
}

// ------------------------ origin_statement的递归子程序
void semantics_class::origin_statement()
{
	parser_class::origin_statement();		// 语法分析获取语法树(由parser中的属性保存)

	Origin_x = get_tree_value(x_ptr);		// 根据语法树计算横坐标的平移距离
	delete_tree(x_ptr);

	Origin_y = get_tree_value(y_ptr);		// 根据语法树计算纵坐标的平移距离
	delete_tree(y_ptr);
}

// ------------------------ scale_statement的递归子程序
void semantics_class::scale_statement () 
{
	parser_class::scale_statement();		// 语法分析获取语法树(由parser中的属性保存)

	Scale_x = get_tree_value(x_ptr);		// 根据语法树计算横坐标的比例因子
	delete_tree(x_ptr);

	Scale_y = get_tree_value(y_ptr);		// 根据语法树计算纵坐标的比例因子
	delete_tree(y_ptr);
}

// ------------------------ rot_statement的递归子程序
void semantics_class::rot_statement () 
{	
	parser_class::rot_statement();			// 语法分析获取语法树(由parser中的属性保存)
	rot_angle = get_tree_value(angle_ptr);	// 根据语法树计算旋转角度
	delete_tree(angle_ptr);
}

// ------------------------ for_statement 的递归子程序
void semantics_class::for_statement () 
{	
	double start_val, end_val, step_val;	// 绘图起点、终点、步长

	parser_class::for_statement();			// 语法分析获取各表达式的语法树(由parser中的属性保存)
	
	start_val = get_tree_value(start_ptr);	// 计算起点表达式的值
	end_val = get_tree_value(end_ptr);		// 计算终点表达式的值
	step_val = get_tree_value(step_ptr);	// 计算步长表达式的值

	draw_loop (start_val, end_val, step_val, x_ptr, y_ptr); // 绘图

	delete_tree(start_ptr);					// 释放空间
	delete_tree(end_ptr);
	delete_tree(step_ptr);
	delete_tree(x_ptr);	
	delete_tree(y_ptr);	
}

// ---------------------- 用于语法分析器中的跟踪调试, 此处不再起作用
void semantics_class::enter() {}
void semantics_class::back() {}
void semantics_class::call_match() {} 
void semantics_class::tree_trace() {}

⌨️ 快捷键说明

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