Projects > GC Project > compilation_defs.h

Home | Projects | Links

 

GC PROJECT

  

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){     //BINARY

                                        if(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

 

Get WinRAR

 

 

Copyright © Yuri Bulankov 2002

 

Bugs/Comments: code@compilerabuse.com

Copyright (C) 2001-2006 Yuri Bulankov. All rights reserved.