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

📄 funcdraw.y

📁 编译原理实验
💻 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 + -