?? parser.cpp
字號:
// Parser.cpp: implementation of the CParser class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Parser.h"
#include <stdio.h>
#include <stdarg.h>
#include <windows.h>
#include <wingdi.h>
#define enter(x)
#define back(x)
#define Tree_trace(x)
#define call_match(x)
#define color RGB(0,0,0)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CParser::CParser()
{
}
CParser::~CParser()
{
}
void CParser::Parser(char *FileName,HDC hDC)
{
hdc = hDC;
enter("Parser");
if(!mylex.InitLex(FileName))
{
MessageBox(NULL,"Cannot Open Source File!\n","Wrong!",MB_OK);
return;
}
FetchToken();
Program();
mylex.CloseLex();
back("Parser");
}
void CParser::FetchToken()
{
m_token = mylex.GetToken();
if(m_token.type == ERRTOKEN)
SyntaxError(1);
}
void CParser::SyntaxError(int caseof)
{
switch(caseof)
{
case 1:ErrMsg(mylex.m_LineNo,"錯誤記號:",m_token.lexeme);break;
case 2:ErrMsg(mylex.m_LineNo,"不是預期記號:",m_token.lexeme);break;
}
}
void CParser::ErrMsg(int LineNo,char *descrip,char *str)
{
char msg[256];
memset(msg,0,256);
sprintf(msg,"Line No %5d:%s %s!",LineNo,descrip,str);
MessageBox(NULL,msg,"error",MB_OK);
mylex.CloseLex();
}
void CParser::Program()
{
enter("Program");
while(m_token.type != NONTOKEN)
{
Statement();
MatchToken(SEMICO);
}
back("Program");
}
void CParser::Statement()
{
enter("Statement");
switch(m_token.type)
{
case ORIGIN:OrignStatement();break;
case SCALE:ScaleStatement();break;
case ROT:RotStatement();break;
case FOR:ForStatement();break;
default:SyntaxError(2);break;
}
back("Statement");
}
void CParser::MatchToken(enum Token_Type tokentype)
{
if(m_token.type != tokentype)
SyntaxError(2);
FetchToken();
}
void CParser::OrignStatement()
{
struct ExprNode * tmp;
enter("OrignStatement");
MatchToken(ORIGIN);
MatchToken(IS);
MatchToken(L_BRACKET);
tmp = Expression();
Origin_x = GetExprValue(tmp);
DelExprTree(tmp);
MatchToken(COMMA);
tmp = Expression();
Origin_y = GetExprValue(tmp);
DelExprTree(tmp);
MatchToken(R_BRACKET);
back("OrignStatement");
}
ExprNode *CParser::Expression()
{
struct ExprNode *left,*right;
Token_Type token_tmp;
enter("Expression");
left = Term();
while((m_token.type == PLUS) || (m_token.type == MINUS))
{
token_tmp = m_token.type;
MatchToken(token_tmp);
right = Term();
left = MakeExprNode(token_tmp,left,right);
}
Tree_trace(left);
back("Exprssion");
return left;
}
ExprNode *CParser::Term()
{
struct ExprNode *left,*right;
Token_Type token_tmp;
left = Factor();
while((m_token.type == MUL) || (m_token.type == DIV))
{
token_tmp = m_token.type;
MatchToken(token_tmp);
right = Factor();
left = MakeExprNode(token_tmp,left,right);
}
return left;
}
ExprNode * CParser::Factor()
{
struct ExprNode *left,*right;
if(m_token.type == PLUS)
{
MatchToken(PLUS);
right = Factor();
}
else if(m_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 = Comp();
return right;
}
ExprNode* CParser::Comp()
{
struct ExprNode *left,*right;
left = AtomComp();
if(m_token.type == POWER)
{
MatchToken(POWER);
right = Comp();
left = MakeExprNode(POWER,left,right);
}
return left;
}
struct ExprNode * CParser::AtomComp()
{
struct Token t = m_token;
struct ExprNode *address,*tmp;
switch(t.type)
{
case CONST_ID:
MatchToken(CONST_ID);
address = MakeExprNode(CONST_ID,t.value);
break;
case L_BRACKET:
MatchToken(L_BRACKET);
address = Expression();
MatchToken(R_BRACKET);
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;
default:
SyntaxError(2);
break;
}
return address;
}
struct ExprNode * CParser::MakeExprNode(enum Token_Type opcode,...)
{
struct ExprNode*ExprPtr = new 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 = (ExprNode*)va_arg(ArgPtr,ExprNode *) ;
break;
default:
ExprPtr->Content.CaseOperator.Left = (ExprNode*)va_arg(ArgPtr,ExprNode*);
ExprPtr->Content.CaseOperator.Right = (ExprNode*)va_arg(ArgPtr,ExprNode*);
break;
}
va_end(ArgPtr);
return ExprPtr;
}
void CParser::PrintSyntaxTree(ExprNode*root,int indent)
{
int tmp;
for(tmp = 1;tmp <= indent;tmp++)
{
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");break;
}
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 CParser::DelExprTree(ExprNode*root)
{
if(root)
{
switch(root->OpCode)
{
case PLUS:
case MUL:
case MINUS:
case DIV:
case POWER:
DelExprTree(root->Content.CaseOperator.Left);
DelExprTree(root->Content.CaseOperator.Right);
break;
case FUNC:
DelExprTree(root->Content.CaseFunc.Child);
break;
default:break;
}
delete(root);
}
}
double CParser::GetExprValue(ExprNode *root)
{
if(NULL == root)
return 0.0;
switch(root->OpCode)
{
case PLUS:
return GetExprValue(root->Content.CaseOperator.Left) +
GetExprValue(root->Content.CaseOperator.Right);
break;
case MINUS:
return GetExprValue(root->Content.CaseOperator.Left) -
GetExprValue(root->Content.CaseOperator.Right);
break;
case MUL:
return GetExprValue(root->Content.CaseOperator.Left) *
GetExprValue(root->Content.CaseOperator.Right);
break;
case DIV:
return GetExprValue(root->Content.CaseOperator.Left) /
GetExprValue(root->Content.CaseOperator.Right);
break;
case POWER:
return pow(GetExprValue(root->Content.CaseOperator.Left),
GetExprValue(root->Content.CaseOperator.Right));
break;
case FUNC:
return (*(root->Content.CaseFunc.MathFuncPtr))(GetExprValue(root->Content.CaseFunc.Child));
break;
case CONST_ID:
return root->Content.CaseConst;
break;
case T:
return *(root->Content.CaseParmPtr);
break;
default :return 0.0;
}
}
void CParser::ScaleStatement(void)
{
struct ExprNode*tmp;
enter("ScaleStatement");
MatchToken(SCALE);
MatchToken(IS);
MatchToken(L_BRACKET);
tmp = Expression();
Scale_x = GetExprValue(tmp);
DelExprTree(tmp);
MatchToken(COMMA);
tmp = Expression();
Scale_y = GetExprValue(tmp);
DelExprTree(tmp);
MatchToken(R_BRACKET);
back("ScaleStatement");
}
void CParser::RotStatement(void)
{
struct ExprNode*tmp;
enter("RotStatement");
MatchToken(ROT);
MatchToken(IS);
tmp = Expression();
Rot_angle = GetExprValue(tmp);
DelExprTree(tmp);
back("RotStatement");
}
void CParser::ForStatement(void)
{
double Start,End,Step;
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();
Start = GetExprValue(start_ptr);
DelExprTree(start_ptr);
MatchToken(TO);call_match("TO");
end_ptr = Expression();
End = GetExprValue(end_ptr);
DelExprTree(end_ptr);
MatchToken(STEP);call_match("STEP");
step_ptr = Expression();
Step = GetExprValue(step_ptr);
DelExprTree(step_ptr);
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(")");
DrawLoop(Start,End,Step,x_ptr,y_ptr);
DelExprTree(x_ptr);
DelExprTree(y_ptr);
back("ForStatement");
}
void CParser::DrawLoop(double Start,double End,double Step,
ExprNode*HorPtr,ExprNode*VerPtr)
{
for(Parameter = Start;Parameter <= End;Parameter += Step)
{
CalcCoord(HorPtr,VerPtr);
DrawPixel();
}
}
void CParser::CalcCoord(ExprNode*Hor_Exp,ExprNode*Ver_Exp)
{
double HorCord,VerCord,tmp;
double cx,cy;
HorCord = GetExprValue(Hor_Exp);
VerCord =GetExprValue(Ver_Exp);
HorCord *= Scale_x;
VerCord *= Scale_y;
tmp = HorCord*cos(Rot_angle) + VerCord * sin(Rot_angle);
VerCord = VerCord*cos(Rot_angle) - HorCord*sin(Rot_angle);
HorCord = tmp;
cx = 2*HorCord + Origin_x;
cy = 2*VerCord + Origin_y;
x = cx;
y = cy;
}
void CParser::DrawPixel()
{
SetPixel(hdc,(int)x,(int)y,color);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -