|
Projects > GC Project > compilation_defs.h |
||||
|
compilation.h compilation_defs.h exp_info.h GCMainDialog.h on_apply.h setaxis.h Download gc.exe (1.63 MB) Download VC++ 8.0 Project (54.1 KB RAR Archive) GC Help
#ifndef COMPILATION_DEFS_H#define COMPILATION_DEFS_H
//IMPLEMENTATION OF KEY COMPILATION MEMBER METHODS:
//CHAR CHECK ***************************************************************************** //Performs simple string check, to find most obvious errors: bool compilation::char_check(CString & formula){
int bracket_count=0;wchar_t a=0;int i=0;
if (formula.IsEmpty()){er.error("nothing has been entered");return 0;}
while (i<formula.GetLength()){ a=formula[i]; if (a=='(' || a=='[' || a=='{'){formula.SetAt(i,'(');bracket_count++;} else if (a==')' || a==']' || a=='}'){formula.SetAt(i,')');bracket_count--; if (bracket_count<0){er.error("unbalanced right parenthes(i|e)s");return 0;}} else if (a<32 || a>126) {er.error("unrecognized token(s)");return 0;}else if (a>32 && a<40) {er.error("unrecognized token(s)");return 0;}else if (a==58 || a==59 || a==60 ||a==62 ||a==63 ||a==64||a==95 ||a==96 ||a==124 || a==44 ||a==92) {er.error("unrecognized token(s)");return 0;}
i++; }
if (bracket_count>0) { er.error("missing right parenthes(i|e)s");return 0;}
return 1;}
//SEPARATOR//************************************************************************** //Separates function names from var. names, from constants, //from operands, from brackets:
void compilation::separate(CString & frml){//The user will have to separate function names("abs","cos" etc) and "pi" //from the same kind of identifiers with spaces or brackets to avoid errors.
CString t_frml;int i=0,l=frml.GetLength();while (i<l){ if ((isdigit(frml[i])) || frml[i]=='.'){while ((isdigit(frml[i])) || frml[i]=='.'){t_frml+=frml[i++];if(i>=l){break;}} t_frml+=' ';}
else if (frml[i]=='-' ||frml[i]=='+'||frml[i]=='*'||frml[i]=='/'||frml[i]=='^'||frml[i]==')'||frml[i]=='(') {t_frml+=frml[i];t_frml+=' ';i++;}
//exp() function exception: (the 'X' issue) else if ((frml[i]=='e' || frml[i]=='E') && i+2<=l &&(frml[i+1]=='x' || frml[i+1]=='X') && (frml[i+2]=='p' || frml[i+2]=='P')) {t_frml+='e';t_frml+='x';t_frml+='p';t_frml+=' ';i+=3;}
else if ((frml[i]=='X' || frml[i]=='x')){t_frml+='X';t_frml+=' ';i++;}
else if (isalpha(frml[i])){while(isalpha(frml[i])) { if ((frml[i]=='p' || frml[i]=='P') && (frml[i+1]=='i' || frml[i+1]=='I')){t_frml+="pi";i+=2;break;} t_frml+=(char)tolower(frml[i++]);if(i>=l){break;} } t_frml+=' '; }
else i++;} frml=t_frml; }
//TOKENIZER ****************************************************************************** void compilation::tokenize(CString & str,LIST<CString> & str_t){ int i=0;CString temp;while (i<str.GetLength()){if (str[i]==' '){i++;str_t.atb(temp);temp="";}else temp+=str[i++];} }
//======================================================================================== // TRANSLATION //======================================================================================== bool compilation::translate(LIST<CString> & t_formula, LIST<expinfo> & ei_list){// The default(omited) multiplication operators are inserted by this function
int j=1;expinfo * temp,* temp2;
while (j<=t_formula.getsize()){temp=new expinfo(t_formula[j++]);
if (temp->op==ERR){er.error("unrecognized token(s)");delete temp;return 0;}
if (temp->op==NUM && (ei_list.last && ei_list.last->value.op==NUM)){er.error("operator(s) missing");return 0;}
if ((temp->op==NUM || temp->op==VAR || temp->op==LEFTPAREN || temp->op==PI|| (temp->op>=5 && temp->op<=22)) && ((ei_list.last) && (ei_list.last->value.op==NUM || ei_list.last->value.op==VAR || ei_list.last->value.op==PI || ei_list.last->value.op==RIGHTPAREN))) {temp2=new expinfo("def*");ei_list.atb(*temp2);delete temp2;}
ei_list.atb(*temp); delete temp;}
// CORRECTIONS (for unary operators: -, +, /) //----------------------------------------------------------------------------------------
int position=1;while (position<=ei_list.getsize()){if (ei_list[position].op==BIMINUS || ei_list[position].op==BIPLUS || ei_list[position].op==BIDIV)if ((position==1) || !(ei_list[position-1].op==RIGHTPAREN ||ei_list[position-1].op==NUM || ei_list[position-1].op==VAR || ei_list[position-1].op==PI)) { switch (ei_list[position].op){ case BIMINUS: ei_list[position].op=UMINUS;ei_list[position].prec=3;ei_list[position].p_calc=&expinfo::u_minus_f;break; case BIPLUS: ei_list[position].op=UPLUS;ei_list[position].prec=3;ei_list[position].p_calc=&expinfo::u_plus_f;break; case BIDIV: ei_list[position].op=UDIV;ei_list[position].prec=3;ei_list[position].p_calc=&expinfo::u_divide_f;break;
default :{er.error("corrections: this should never happen!!! unexpected operator");return 0;}} } position++; }
// OPERAND PRESENCE CHECK //---------------------------------------------------------------------------------------- position=1; bool operands_present=false;while (position<=ei_list.getsize()){if (ei_list[position].op==NUM || ei_list[position].op==PI || ei_list[position].op==VAR)operands_present=true; position++; }
//---------------------------------------------------------------------------------------- if (!operands_present){er.error("operand(s) missing");return 0;}
return 1;}
//======================================================================================== // BUILD //======================================================================================== //Functions that create connections between 'expinfo' nodes: expinfo * compilation::build(LIST<expinfo> & ei_list, int & i){
STACK<expinfo *> operator_stack; STACK<expinfo *> operand_stack;
expinfo * temp_ei=0; expinfo * top_op=0;
while (i<=ei_list.getsize()){
temp_ei=&(ei_list[i++]);
if (temp_ei->op==RIGHTPAREN) break;
else if (temp_ei->op==LEFTPAREN){top_op=build(ei_list,i); operand_stack.push(top_op);}
else if (temp_ei->op==NUM || temp_ei->op==VAR || temp_ei->op==PI) {operand_stack.push(temp_ei);}
else if (temp_ei->op<=22 && temp_ei->op>=5){operator_stack.push(temp_ei);} //UNARY
else {while(operator_stack.top(top_op) && temp_ei->prec >= top_op->prec){ //BINARYif (top_op->op < 23) {do_unary(top_op,operand_stack);operator_stack.pop();}else {do_binary(top_op,operand_stack);operator_stack.pop();}} operator_stack.push(temp_ei); } }
if (operator_stack.is_empty() && !operand_stack.is_empty()){operand_stack.top(top_op);}else while (!operator_stack.is_empty()){operator_stack.top(top_op); if (top_op->op < 23) {do_unary(top_op,operand_stack);operator_stack.pop();}else {do_binary(top_op,operand_stack);operator_stack.pop();}}
return top_op;}
//======================================================================================== // OPERATOR PROCESSING //========================================================================================
void compilation::do_binary(expinfo * ei, STACK<expinfo *> & O_ST){
expinfo * temp; if (O_ST.getsize()<2){er.error("operand(s) missing");all_correct=0;return;}
O_ST.top(temp); ei->right=temp; O_ST.pop();
O_ST.top(temp); ei->left=temp; O_ST.pop();
O_ST.push(ei); }
void compilation::do_unary(expinfo * ei, STACK<expinfo *> & O_ST){
expinfo * temp; if (O_ST.getsize()<1){er.error("operand(s) missing");all_correct=0;return;}
O_ST.top(temp); ei->right=temp; O_ST.pop();
O_ST.push(ei); } //========================================================================================
#endif
compilation.h compilation_defs.h exp_info.h GCMainDialog.h on_apply.h setaxis.h Download gc.exe (1.63 MB) Download VC++ 8.0 Project (54.1 KB RAR Archive) GC Help
Copyright © Yuri Bulankov 2002
|
||||
|
Bugs/Comments: code@compilerabuse.com Copyright (C) 2001-2006 Yuri Bulankov. All rights reserved. |
||||