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

📄 parser.cpp

📁 简单绘图语言
💻 CPP
字号:
#include "parser.h"

#ifndef  PARSER_DEBUG 
#include "semantic.h"
#endif

#ifdef PARSER_DEBUG
 #define enter(x)  printf("enter in ");printf(x);printf("\n")
#else
 #define enter(x)
#endif

#ifdef PARSER_DEBUG
   #define back(x) printf("exit from ");printf(x); printf("\n")
#else
   #define back(x)
#endif

#ifdef PARSER_DEBUG
   #define call_match(x) printf("matchtoken ");printf(x); printf("\n")
#else
   #define call_match(x)
#endif

#ifdef PARSER_DEBUG
   #define Tree_trace(x) PrintSyntaxTree(x,1);
#else
   #define Tree_trace
#endif

#ifdef PARSER_DEBUG
   double Parameter=0;              //参数T的存储空间
#else
   double Parameter=0,              //参数T的存储空间
          Origin_x=0,Origin_y=0,    //横、纵平移距离
		  Scale_x=1, Scale_y=1,     //横、纵比例因子
		  Rot_angle=0;              //旋转角度
#endif
static Token token;                 //记号

//----------------辅助函数声明
static void FecthToken();
static void MatchToken(enum Token_Type AToken);
static void SyntaxError(int case_of);
static void ErrMsg(unsigned LineNo, char *descrip, char *string);
static void PrintSyntaxTree(struct ExprNode *root, int indent);

//----------------非终结符的递归子程序声明
static void Program();
static void Statement();
static void OriginStatement();
static void RotStatement();
static void ScaleStatement();
static void ForStatement();
static struct ExprNode* Expression();
static struct ExprNode* Term();
static struct ExprNode* Factor();
static struct ExprNode* Component();
static struct ExprNode* Atom();

//---------------外部接口与语法树构造函数声明
extern void Parser(char* SrcFilePtr);
static struct ExprNode* MakeExprNode(enum Token_Type opcode,...);

//---------------通过词法分析器接口GETTOKEN获取一个记号
static void FetchToken()
{
	token = GetToken();
	if(token.type==ERRTOKEN)  SyntaxError(1);
}

//----------------匹配记号
static void MatchToken(enum Token_Type The_Token)
{
	if(token.type!=The_Token) SyntaxError(2);
	FetchToken();
}

//----------------语法错误处理
static void SyntaxError(int case_of)
{
	switch(case_of)
	{
	case 1: ErrMsg(LineNo,"错误",token.lexeme);
		    break;
	case 2: ErrMsg(LineNo,"不是预期记号",token.lexeme);
		    break;
	}
}

//-----------------打印错误信息
void ErrMsg(unsigned LineNo, char *descrip, char *string)
{
#ifdef PARSER_DEBUG
	printf("Line No %5d:%s%s!\n",LineNo,descrip,string);
#else
	char msg[256];
	memset(msg,0,256);
	sprintf(msg, "Line No %5d:%s%s!",LineNo,descrip,string);
#endif

#ifdef _VC_COMPILER
	MessageBox(NULL,msg,"error!",MB_OK);
#endif

#ifdef _BC_COMPILER
	printf("%s\n",msg);
#endif

	CloseScanner();
	exit(1);
}

//------------先序遍历并打印表达式的语法树
void PrintSyntaxTree(struct ExprNode *root, int indent)
{
	int temp;
	for(temp=1; temp<=indent; temp++) printf("\t");   //缩进
	switch(root->OpCode)                              //打印根节点
	{
	    case PLUS:     printf("%s\n","+"); break;
		case MINUS:    printf("%s\n","-"); break;
		case MUL:      printf("%s\n","*"); break;
		case DIV:      printf("%s\n","/"); break;
		case POWER:    printf("%s\n","**");break;
		case FUNC:     printf("%x\n",root->Content.CaseFunc.MathFuncPtr);
			           break;
		case CONST_ID: printf("%f\n",root->Content.CaseConst);
			           break;
		case T:        printf("%s\n","T");
			           break;
		default:       printf("Error Tree Node!\n");
			           exit(0);
	}
	if(root->OpCode==CONST_ID||root->OpCode==T)    //叶子节点返回
		return;
	if(root->OpCode==FUNC)                         //递归打印一个孩子的节点
		PrintSyntaxTree(root->Content.CaseFunc.Child,indent+1);
	else
	{
		PrintSyntaxTree(root->Content.CaseOperator.Left, indent+1);
        PrintSyntaxTree(root->Content.CaseOperator.Right, indent+1);
	}
}

//------------------绘图语言解释器入口
void Parser(char *SrcFilePtr)
{
    enter("Parser");
	if(!InitScanner(SrcFilePtr))
	{printf("Open Source File Error!\n"); return;}
	FetchToken();
	Program();
	CloseScanner();
	back("Parser");
	return;
}

//------------------------program的递归子程序
static void Program()
{
	enter("Program");
	while (token.type!=NONTOKEN)
	{
		Statement();
		MatchToken(SEMICO);
	}
	back("Program");
}

//------------Statement的递归子程序
static void Statement()
{
	enter("Statement");
	switch(token.type)
	{
	     case ORIGIN: OriginStatement(); break;
		 case SCALE:  ScaleStatement();  break;
		 case ROT:    RotStatement();    break;
		 case FOR:    ForStatement();    break;
		 default:     SyntaxError(2);
	}
	back("Statement");
}

//-------------OriginStatement的递归子程序
static void OriginStatement(void)
{
	struct ExprNode *tmp;
	enter("OriginStatement");
	MatchToken(ORIGIN);
	MatchToken(IS);
	MatchToken(L_BRACKET);
	tmp = Expression();
#ifndef PARSER_DEBUG
	Origin_x = GetExprValue(tmp);   //获取横坐标的平移距离
	DelExprTree(tmp);
#endif
	MatchToken(COMMA);
	tmp = Expression();
#ifndef PARSER_DEBUG
    Origin_y = GetExprValue(tmp);   //获取纵坐标的平移距离
	DelExprTree(tmp);
#endif
	MatchToken(R_BRACKET);
	back("OriginStatement");
}

//-------------ScaleStatement的递归子程序
static void ScaleStatement(void)
{
	struct ExprNode *tmp;
	enter("ScaleStatement");
	MatchToken(SCALE);
	MatchToken(IS);
	MatchToken(L_BRACKET);
	tmp = Expression();
#ifndef PARSER_DEBUG
	Scale_x = GetExprValue(tmp);   //获取横坐标的比例因子
	DelExprTree(tmp);
#endif
	MatchToken(COMMA);
	tmp = Expression();
#ifndef PARSER_DEBUG
    Scale_y = GetExprValue(tmp);   //获取纵坐标的比例因子
	DelExprTree(tmp);
#endif
	MatchToken(R_BRACKET);
	back("ScaleStatement");
}

//-------------RotStatement的递归子程序
static void RotStatement(void)
{
	struct ExprNode *tmp;
	enter("RotStatement");
	MatchToken(ROT);
	MatchToken(IS);
	tmp = Expression();
#ifndef PARSER_DEBUG
	Rot_angle = GetExprValue(tmp);   //获取旋转角度
	DelExprTree(tmp);
#endif
	
	back("RotStatement");
}

//-------------ForStatement的递归子程序
static void ForStatement(void)
{
#ifndef PARSER_DEBUG
	double Start, End, Step;      //绘图起点、终点、步长
#endif
	struct ExprNode *start_ptr,*end_ptr,*step_ptr,
		            *x_ptr,*y_ptr;  //各表达式语法树根节点指针

	enter("ForStatement");
	MatchToken(FOR);   call_match("FOR"); 
	MatchToken(T);     call_match("T");
	MatchToken(FROM);  call_match("FROM");
	start_ptr = Expression();       //构造参数起点表达式的语法树
	
#ifndef PARSER_DEBUG
	Start = GetExprValue(start_ptr);   //计算参数起点表达式的值
	DelExprTree(start_ptr);            //释放参数起点语法树所占空间
#endif
	MatchToken(TO);   call_match("TO");
	end_ptr = Expression();            //构造参数终点表达式的语法树
#ifndef PARSER_DEBUG
	End = GetExprValue(end_ptr);       //计算参数终点表达式的值
	DelExprTree(end_ptr);              //释放参数终点语法树所占空间
#endif
	MatchToken(STEP);   call_match("STEP");
	step_ptr = Expression();           //构造参数步长表达式的语法树
#ifndef PARSER_DEBUG
	Step = GetExprValue(step_ptr);     //计算参数步长表达式的值
	DelExprTree(step_ptr);             //释放参数步长语法树所占空间
#endif
	MatchToken(DRAW);        call_match("DRAW");
	MatchToken(L_BRACKET);   call_match("(");
	x_ptr = Expression();              //构造横坐标表达式的语法树
	MatchToken(COMMA);       call_match(",");
	y_ptr = Expression();              //构造纵坐标表达式的语法树
	MatchToken(R_BRACKET);   call_match(")");

#ifndef PARSER_DEBUG
	DrawLoop(Start,End,Step,x_ptr,y_ptr);//绘制图形
	DelExprTree(x_ptr);                 //释放横坐标语法树所占空间
	DelExprTree(y_ptr);                 //释放纵坐标语法树所占空间
#endif
	back("ForStatement");
}

//-------------Expression的递归子程序
static struct ExprNode* Expression()
{
	struct ExprNode *left, *right;      //左右子树节点的指针
	Token_Type token_tmp;               //当前记号

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

//-------------Term的递归子程序
static struct ExprNode* Term()
{
	struct ExprNode *left, *right;      
	Token_Type token_tmp;               

	left = Factor();                  
	while(token.type==MUL || token.type==DIV)
	{
		token_tmp = token.type;
		MatchToken(token_tmp);
		right = Factor();             
		left = MakeExprNode(token_tmp,left,right);                         
	}
	return left;                      
}

//-------------Term的递归子程序
static struct ExprNode* Factor()
{
	struct ExprNode *left, *right;      
                 
	if(token.type==PLUS)             //匹配一元加运算
	{
		MatchToken(PLUS);
		right = Factor();           //表达式退化为仅有右操作数的表达式             
		                  
	}
	else if(token.type==MINUS)      //匹配一元减运算
	{
		MatchToken(MINUS);          //表达式转化为二元减运算表达式            
		right = Factor();
		left = new ExprNode;
		left->OpCode = CONST_ID;
		left->Content.CaseConst = 0.0;
		right = MakeExprNode(MINUS, left, right);
	}
	else right = Component();        //匹配非终结符Component
	return right;
}

//-------------Component的递归子程序
static struct ExprNode* Component()
{
	struct ExprNode *left, *right;      
	left = Atom();
                 
	if(token.type==POWER)
	{
		MatchToken(POWER);
		right = Component();        //递归调用Component以实现POWER的右结合
		left = MakeExprNode(POWER,left,right);
	}
	return left;
}

//-------------Atom的递归子程序
static struct ExprNode* Atom()
{
	struct Token t=token;      
	struct ExprNode *address, *tmp; 
	                 
	switch(token.type)
	{
	case CONST_ID:
		MatchToken(CONST_ID);
		address = MakeExprNode(CONST_ID,t.values);
		break;
	case T:
		MatchToken(T);
		address = MakeExprNode(T);
		break;
	case FUNC:
		MatchToken(FUNC);
		MatchToken(L_BRACKET);
		tmp = Expression();
		address = MakeExprNode(FUNC,t.FuncPtr,tmp);
        MatchToken(R_BRACKET);
		break;
	case L_BRACKET:
		MatchToken(L_BRACKET);
		address = Expression();
		MatchToken(R_BRACKET);
        break;
	default:
		SyntaxError(2);
	}
	return address;
}

//-------------生成语法树的一个节点
static struct ExprNode* MakeExprNode(enum Token_Type opcode,...)
{
	struct ExprNode *ExprPtr = new(struct ExprNode);
	ExprPtr->OpCode = opcode;          //接收记号的类别
	va_list ArgPtr;
	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;
}


extern void Parser(char* SrcFilePtr);
void main(int argc,char *argv[])
{
#ifdef PARSER_DEBUG
	if(argc<2)
	{
		printf("please input Source File!\n");
	}
	Parser("1.txt");
#endif
	
}

⌨️ 快捷键说明

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