📄 source.txt
字号:
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 = ¶meter;
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 + -