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

📄 parser.cpp

📁 用VC++实现了一个编译器的功能
💻 CPP
字号:
#include "parser.h"
#include "scan.h"
#include <iostream>
using namespace std;


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

#ifdef PARSER_DEBUG
#define enter(x) cout << "enter in   " << x << endl;
#else
#define enter(x)
#endif

#ifdef PARSER_DEBUG
#define back(x) cout << "exit from   " << x << endl;
#else
#define back(x)
#endif

#ifdef PARSER_DEBUG
#define call_match(x) cout << "matchtoken   " << x << endl;
#else
#define call_match(x)
#endif

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

#ifdef PARSER_DEBUG
       double Start,End,Step;
#endif

#ifdef PARSER_DEBUG
double Parameter=0;
#else
double Parameter=0,
       Origin_x=0,Origin_y=0,
	   Scale_x=1,Scale_y=1,
       Rot_angle=0;
#endif


static Token token;
  

void FetchToken();
void MatchToken(enum Token_Type AToken);
void SyntaxError(int case_of);
void ErrMsg(unsigned LineNo,char *descrip,char *string);
void PrintSyntaxTree(struct ExprNode *root,int indent);


void Program();
void Statement();
void OriginStatement();
void RotStatement();
void ScaleStatement();
void ForStatement();
struct ExprNode *Expression();
struct ExprNode *Term();
struct ExprNode *Factor();
struct ExprNode *Component();
struct ExprNode *Atom();


extern void Parser(char *SrcFilePtr);
static struct ExprNode * MakeExprNode(enum Token_Type opcode,...);


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," Error Token! ",token.lexeme);
                break;
     case 2:    ErrMsg(LineNo," Unexpected token! ",token.lexeme);
		        break;
}
}


void ErrMsg(unsigned LineNo,char *descrip,char *string)
{   
#ifdef  PARSER_DEBUG
        printf("LineNO %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_COMPILEP
        printf("%s\n",msg);
    #endif

    CloseScanner();
	exit(1);
}


void PrintSyntaxTree(struct ExprNode *root,int indent)
{   
    for( int i=1; i <= indent; i++ )
		printf("\t");

	switch(root->OpCode)
	{   case PLUS:     cout << "+" << endl;  break;
	    case MINUS:    cout << "-" << endl;  break;
        case MUL:      cout << "*" << endl;  break;
		case DIV:      cout << "/" << endl;  break;
		case POWER:    cout << "**" << endl;  break;
		case FUNC:     cout << root->Content.CaseFunc.MathFuncPtr << endl;
		               break;
		case CONST_ID:   cout << root->Content.CaseConst << endl;    break;
		case T:        printf("%s\n","T");     break;
		default:       cout << "Error Tree Node! "<< endl;
					   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");
	cout << "Parser" << endl;
    if(!InitScanner(SrcFilePtr))
	{	cout << "Open Source File Error!" << endl;
	        return;
	} 
	
	FetchToken();
	Program();
	CloseScanner();
	//back("Parser");
	cout << "exit from Parser!" << endl;
	return;
}


static void Program()
{   //enter("Program");
	cout << " enter into Program!" << endl;
    while(token.type != NONTOKEN)
	{  Statement();
	   MatchToken(SEMICO);
	}
	//back("Program");
	cout << " exit from Program!" << endl;
}


static void Statement()
{   //enter("Statement");
	cout << " enter into Statement!" << endl;
    switch(token.type)
	{   case ORIGIN:     OriginStatement();    break;
	    case SCALE:      ScaleStatement();     break;
		case ROT:        RotStatement();       break;
		case FOR:        ForStatement();       break;
		default:         SyntaxError(2);    
	}
	//back("Statement");
	cout << " exit from Statement!" << endl;
}



static void OriginStatement(void)
{   struct ExprNode *tmp;
    //enter("OriginStatement");
    cout << "enter into OriginStatement!" << endl;
	MatchToken(ORIGIN);
	MatchToken(IS);
	MatchToken(L_BRACKET);
	tmp = Expression();
#ifdef PARSER_DEBUG
	   Origin_x = GetExprValue(tmp);
	   DelExprTree(tmp);
#endif
	MatchToken(COMMA);
	tmp = Expression();
#ifdef PARSER_DEBUG
	Origin_y = GetExprValue(tmp);
	DelExprTree(tmp);
#endif
	MatchToken(R_BRACKET);
	//back("OriginStatement");
	cout << " exit from OriginStatement! " << endl;
}



static void ScaleStatement(void)
{   struct ExprNode *tmp;
     
    //enter("ScaleStatement");
    cout << "enter into ScaleStatement!" << endl;
	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");
	 cout << "exit from ScaleStatement!" << endl;
}



static void RotStatement(void)
{   struct ExprNode *tmp;
    

    //enter("RotStatement");
    cout << "enter into RotStatement!" << endl;
    MatchToken(ROT);
	MatchToken(IS);
	tmp = Expression();
 /* #ifndef PARSER_DEBUG
	 Rot_angle = GetExprValue(tmp);
	 DelExprTree(tmp);
#endif*/
	 //back("RotStatement");
	 cout << "exit from RotStatement!" << endl;
}


 
static void ForStatement()
{  /*#ifndef PARSER_DEBUG
      double Start,End,Step;
   #endif*/
 
    struct ExprNode *start_ptr,*end_ptr,*step_ptr,*x_ptr,*y_ptr;
	//enter("ForStatement");
	cout << "enter into ForStatement!" << endl;
	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();
/*#ifdef 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");
	cout << "exit from ForStatement!" << endl;
}



static struct ExprNode * Expression()
{   struct ExprNode *left,*right;
    Token_Type token_tmp;

	//enter("Expression");
	cout << "enter into Expression!" << endl;
	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);
	PrintSyntaxTree(left,1);
	//back("Expression");
	cout << "exit from Expression!" << endl;
	return left;
}



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;
}



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();
	return right;
}



static struct ExprNode * Component()
{   struct ExprNode *left,*right;

    left = Atom();
	if(token.type == POWER)
	{   MatchToken(POWER);
	    right = Component();
        left = MakeExprNode(POWER,left,right);
	
	}
	return left;
}



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.value);
			  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;
}




#include <stdio.h>
extern void Parser(char * SrcFilePtr);
void main()
{  char *argv;
   argv = "text.txt";
  
   if(!InitScanner(argv))
   {  cout << "Open Source File Error!" << endl;
       
      return;
   }
   Parser(argv);
 
}

     

⌨️ 快捷键说明

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