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

📄 source.txt

📁 编译原理的三个子模块,包括词法分析,语法分析和语义分析,是绘图语言解释器
💻 TXT
📖 第 1 页 / 共 2 页
字号:
	y_ptr = expression();
	match_token (R_BRACKET);
	back("scale_statement");
}

// ------------------------ rot_statement 的递归子程序
void parser_class::rot_statement (tree_node_ptr &angle_ptr) 
{	
	enter("rot_statement");
	match_token (ROT);
	match_token (IS);
    angle_ptr = expression();
	back("rot_statement");
}

// ------------------------ for_statement 的递归子程序
void parser_class::for_statement () 
{	
	enter("for_statement");
	call_match("FOR");	match_token (FOR);
    call_match("T");	match_token(T);
	call_match("FROM");	match_token (FROM);
    start_ptr = expression();			// 构造参数起始表达式语法树
    call_match("TO");	match_token (TO);
	end_ptr = expression();				// 构造参数终结表达式语法树
    call_match("STEP");	match_token (STEP);
	step_ptr = expression();			// 构造参数步长表达式语法树
	call_match("DRAW");	match_token (DRAW);
	call_match("(");	match_token (L_BRACKET);
	x_ptr = expression();	  			// 构造横坐标表达式语法树
	call_match(",");	match_token (COMMA);
	y_ptr = expression(); 				// 构造纵坐标表达式语法树
	call_match(")");	match_token (R_BRACKET);
	back("for_statement");
}

// ------------------------ expression 的递归子程序
tree_node_ptr parser_class::expression()
{	
	tree_node_ptr left, right;		// 左右子树节点的指针
	token_type token_tmp;			// 当前记号

    enter("expression");
	left = term();					// 分析左操作数且得到其语法树
	while (token.type==PLUS || token.type==MINUS)
	{	token_tmp = token.type;
		match_token(token_tmp);
		right = term();				// 分析右操作数且得到其语法树
		left = make_tree_node(token_tmp, left, right);
									// 构造运算的语法树,结果为左子树
	}
	tree_trace(left);				// 打印表达式的语法树
    back("expression");
	return left;					// 返回最终表达式的语法树
}

// ------------------------ term 的递归子程序
tree_node_ptr  parser_class::term()
{	
	tree_node_ptr left, right;
	token_type token_tmp;

    left = factor();
	while (token.type==MUL || token.type==DIV)
	{	token_tmp = token.type;
		match_token(token_tmp);
		right = factor();
		left = make_tree_node(token_tmp, left, right);
	}
	return left;
}

// ------------------------ factor 的递归子程序
tree_node_ptr parser_class::factor ()
{	
	tree_node_ptr left, right;

	if(token.type == PLUS) 			// 匹配一元加运算
	{	match_token(PLUS);
		right = factor();			//  表达式退化为仅有右操作数的表达式
	}
	else if(token.type == MINUS)	// 匹配一元减运算
	{   match_token(MINUS); 		// 表达式转化为二元减运算的表达式
		right = factor();
		left = new tree_node;
		left->op_code = CONST_ID;
		left->content.tag_const = 0.0;
		right = make_tree_node(MINUS, left, right);
	}
	else right = component();		// 匹配非终结符component
	return right;
}

// ------------------------ component 的递归子程序
tree_node_ptr parser_class::component()
{	
	tree_node_ptr left, right;

	left = atom();
	if(token.type == POWER)
	{	match_token(POWER);
		right = component();	// 递归调用component以实现POWER的右结合性质
		left  = make_tree_node(POWER, left, right);
	}
	return left;
}

// ------------------------ atom 的递归子程序
tree_node_ptr parser_class::atom()	
{   
	struct token_rec t=token;
	tree_node_ptr t_ptr, tmp;

	switch (token.type)
	{	case CONST_ID :
			match_token (CONST_ID) ;
			t_ptr = make_tree_node(CONST_ID,t.value);
			break;
		case T:
			match_token(T);
			t_ptr = make_tree_node(T);
			break;
		case FUNC :
			match_token (FUNC);
			match_token (L_BRACKET);
			tmp = expression ();
			t_ptr = make_tree_node(FUNC,t.func_ptr,tmp);
			match_token (R_BRACKET);
			break ;
		case L_BRACKET :
			match_token (L_BRACKET);
			t_ptr = expression ();
			match_token (R_BRACKET);
			break ;
		default :
			syntax_error (2);
	}
	return t_ptr;
}

// ----------------- 生成语法树的一个节点
tree_node_ptr parser_class::make_tree_node(enum token_type opcode, ...)
{	
	tree_node_ptr t_ptr = new (struct tree_node);		// 分配节点存储空间
	t_ptr->op_code = opcode;		// 接收记号的类别
	va_list arg_ptr ;
	va_start (arg_ptr, opcode);
	switch(opcode)					// 根据记号的类别构造不同的节点
	{	case CONST_ID:				// 常数节点
			t_ptr->content.tag_const = (double)va_arg(arg_ptr, double);
			break;
		case T:						// 参数节点
			t_ptr->content.tag_parameter = &parameter;
			break;
		case FUNC:					// 函数调用节点
			t_ptr->content.tag_func.math_func_ptr = (func_ptr)va_arg(arg_ptr, func_ptr);
			t_ptr->content.tag_func.child 
					= tree_node_ptr va_arg (arg_ptr, tree_node_ptr);
			break;
		default:					// 二元运算节点
			t_ptr->content.tag_op.left 
					= tree_node_ptr va_arg (arg_ptr, tree_node_ptr);
			t_ptr->content.tag_op.right
					= tree_node_ptr va_arg (arg_ptr, tree_node_ptr);
			break;
	}
	va_end(arg_ptr);
	return t_ptr;
}

// ---------------------- 用于语法分析器中的跟踪调试
void parser_class::enter(char * x)				{ cout << "enter in  "    << x << endl; }
void parser_class::back(char * x)				{ cout << "exit from  "   << x << endl; }
void parser_class::call_match(char * x)			{ cout << "matchtoken	" << x << endl; } 
void parser_class::tree_trace(tree_node_ptr x)	{ print_syntax_tree(x, 1); }


// ----------------------------- semantics.h ---------------------------------

#include <windows.h>
#include <windows.h>
#include <wingdi.h>
#include "parser.h"

extern HDC hDC;

#define red	  RGB(255, 0, 0)		// 红色
#define black RGB(0,   0, 0)		// 黑色

//---------------- 函数绘图类的声明, 它是parser_class的派生类
class semantics_class : public parser_class {	
protected:
	double Origin_x, Origin_y,			// 横、纵平移距离
		   Scale_x,  Scale_y, 			// 横、纵比例因子
		   rot_angle;					// 旋转角度
public:
	semantics_class()					// 声明对象时置下述初值
	{	Origin_x  = 0;	Origin_y = 0;	// 原点是(0, 0)
		Scale_x   = 1;	Scale_y  = 1;	// 横、纵坐标比例是1:1
		rot_angle = 0;					// 旋转角度是0
	};
	~semantics_class() {};

private:
	// 重置基类parser_class中的方法,以在语法分析的基础上实现语法制导翻译
	void Errmsg (char *string);							// 出错处理
	void error_msg (int line, char *descrip, char *string);// 出错处理
	void statement();
	void for_statement ();
	void origin_statement();
	void rot_statement();
	void scale_statement();
	// 下述函数在semantics_class中被重置为不起作用
	void enter();
    void back();
    void call_match(); 
    void tree_trace();

	// semantics_class中的方法,它们是语法制导翻译中所需的语义函数
    double get_tree_value(tree_node_ptr root);			// 获得表达式的值
	void cal_coord(	tree_node_ptr hor_ptr,				// 计算点的坐标
					tree_node_ptr ver_ptr,
					double &hor_val,
					double &ver_val);
	void draw_pixel(unsigned long x, unsigned long y);	// 绘制一个点
	void draw_loop(	double start_val,						// 图形绘制
					double end_val,
					double step_val,
					tree_node_ptr x_ptr,
					tree_node_ptr y_ptr);
	void delete_tree(tree_node_ptr root);				// 删除一棵树
};


// ----------------------------- 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);
		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)
{
	SetPixel(hDC, x, y, red);
}

// ------------------------ origin_statement的递归子程序
void semantics_class::origin_statement()
{
	tree_node_ptr x_ptr, y_ptr;

	parser_class::origin_statement(x_ptr, y_ptr);		// 语法分析获取语法树

	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 () 
{
	tree_node_ptr x_ptr, y_ptr;

	parser_class::scale_statement(x_ptr, y_ptr);		// 语法分析获取语法树

	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 () 
{	
	tree_node_ptr ptr;

	parser_class::rot_statement(ptr);	// 语法分析获取语法树
	rot_angle = get_tree_value(ptr);		// 根据语法树计算旋转角度
	delete_tree(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);	// 计算起点表达式的值
	delete_tree(start_ptr);	

	end_val = get_tree_value(end_ptr);		// 计算终点表达式的值
	delete_tree(end_ptr);

	step_val = get_tree_value(step_ptr);		// 计算步长表达式的值
	delete_tree(step_ptr);

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

void semantics_class::statement()
{
	switch (token.type)
	{	case ORIGIN	:	origin_statement();	break ;
		case SCALE  :	scale_statement();	break ;
		case ROT    :	rot_statement();	break ;
		case FOR    :	for_statement();	break ;
		default     :	syntax_error(2);		
	}
}

// ---------------------- 用于语法分析器中的跟踪调试, 此处不再起作用
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 + -