📄 funcdraw.y
字号:
// -------------------------- funcdraw.y ------------------------------
%{
# include "semantics.h"
extern int yylex (void) ;
extern unsigned char *yytext;
#define YYSTYPE struct ExprNode * // 重定义语义变量类型为树节点指针
double Parameter=0, // 参数T的存储空间
start=0, end=0, step=0, // 循环绘图语句的起点、终点、步长
Origin_x=0, Origin_y=0, // 横、纵平移距离
Scale_x=1, Scale_y=1, // 横、纵比例因子
Rot_angle=0; // 旋转角度
extern struct Token tokens; // 记号
%}
// ------------- 终结符声明 -------------
%token CONST_ID FUNC FOR FROM DRAW TO STEP ORIGIN SCALE;
%token ROT IS T ERRTOKEN SEMICO COMMA L_BRACKET R_BRACKET;
%left PLUS MINUS;
%left MUL DIV;
%right UNSUB;
%right POWER;
%%
Program : // 程序
| Program Statement SEMICO
;
Statement // 语句
: FOR T FROM Expr TO Expr STEP Expr DRAW L_BRACKET Expr COMMA Expr R_BRACKET
{ start = GetExprValue($4);
end = GetExprValue($6);
step = GetExprValue($8);
DrawLoop(start, end, step, $11, $13) ;
}
| ORIGIN IS L_BRACKET Expr COMMA Expr R_BRACKET
{ Origin_x = GetExprValue($4);
Origin_y = GetExprValue($6);
}
| SCALE IS L_BRACKET Expr COMMA Expr R_BRACKET
{ Scale_x = GetExprValue($4);
Scale_y = GetExprValue($6);
}
| ROT IS Expr
{ Rot_angle = GetExprValue($3);
}
;
Expr // 表达式
: T { $$ = MakeExprNode(T); }
| CONST_ID { $$ = MakeExprNode(CONST_ID, tokens.value); }
| Expr PLUS Expr { $$ = MakeExprNode(PLUS, $1, $3); }
| Expr MINUS Expr { $$ = MakeExprNode(MINUS, $1, $3); }
| Expr MUL Expr { $$ = MakeExprNode(MUL, $1, $3); }
| Expr DIV Expr { $$ = MakeExprNode(DIV, $1, $3); }
| Expr POWER Expr { $$ = MakeExprNode(POWER, $1, $3); }
| L_BRACKET Expr R_BRACKET { $$ = $2; }
| PLUS Expr %prec UNSUB { $$ = $2; }
| MINUS Expr %prec UNSUB
{ $$ = MakeExprNode(MINUS, MakeExprNode(CONST_ID, 0.0), $2); }
| FUNC L_BRACKET Expr R_BRACKET { $$ = MakeExprNode(FUNC, tokens.FuncPtr, $3);}
| ERRTOKEN { yyerror("error token in the input");}
;
%%
// ----------------------- 出错处理
void yyerror (const char *Msg)
{ char errmsg[200];
memset(errmsg,0,200);
sprintf(errmsg, "Line %5d : %s--%s", LineNo, yytext);
MessageBox(NULL, errmsg, Msg, MB_OK);
}
// ----------------------- 生成语法树中的一个节点
struct ExprNode * MakeExprNode(enum Token_Type opcode,...)
{ va_list ArgPtr ;
struct ExprNode *ExprPtr = malloc(sizeof(struct ExprNode));
ExprPtr->OpCode = opcode;
va_start (ArgPtr,opcode) ;
switch(opcode)
{ case CONST_ID:
ExprPtr->Content.CaseConst = (double)va_arg(ArgPtr, double);
break;
case T:
ExprPtr->Content.CaseParmPtr = &Parameter;
break;
case FUNC:
ExprPtr->Content.CaseFunc.MathFuncPtr = (FuncPtr)va_arg(ArgPtr, FuncPtr);
ExprPtr->Content.CaseFunc.Child
= (struct ExprNode *) va_arg (ArgPtr,struct ExprNode *);
break;
default:
ExprPtr->Content.CaseOperator.Left
= (struct ExprNode *)va_arg (ArgPtr,struct ExprNode *);
ExprPtr->Content.CaseOperator.Right
= (struct ExprNode *)va_arg (ArgPtr,struct ExprNode *);
break;
}
va_end(ArgPtr);
return ExprPtr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -