📄 parser.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 + -