Please help me in self documenting the program below.
All u have to do is, take a quick glance at the following code to see if u can understand wat each part is doing. If u have any difficulty in understanding(at a quick glance that is!), pls tell me so that i can add a comment.
Also tell me if i need to change the order in which i defined the functions and classes to enhance readability!
/**********************Definitions of Data Structures Used*********************/
union element
{ char sym;
int ival;
float fval;
};
struct info
{ element el;
char flag;
};
class Queue
{ struct node
{ info inf;
node *next;
}*front,*rear;
public:
Queue()
{front=rear=NULL;}
void push(info n);
info pop();
info peek()
{return front->inf;}
};
class Stack
{ struct node
{ info inf;
node *next;
}*top;
public:
Stack()
{top=NULL;}
void push(info);
info pop();
info peek()
{return top->inf;}
};
/******************************End of definitions******************************/
//Defining Global objects and variables
fstream temp;
Queue expr;
int exp_flag;
/***************************Function declarations******************************/
char symb( char);
void display(Queue);
int insert();
void post_convert();
int evaluate();
int expression();
/****************************End of declarations******************************/
/*******************************Main Function**********************************/
void main()
{ clrscr();
temp.open("temp.mth",ios::out|ios::in);
char ch;
cin.get(ch);
while(ch!=7)
{ exp_flag=0;
if(ch=='=')
{ cin.get(ch);
if(ch=='=')
exp_flag=expression();
else
temp.put('=');
if(exp_flag)
cout<<"Error : Expression syntax error!!";
}
else
temp.put(ch);
cin.get(ch);
}
getch();
}
/********************************End of Main***********************************/
/************************Other Function definitions****************************/
int expression() //converts infix expression to postfix and evaluates
{ exp_flag=0;
int fail=insert();
cout<<"return frm insert()";
if(fail)return -1;
post_convert();
cout<<"\nreturn from post_convert()";
fail=evaluate();
cout<<"\nreturn from evaluate()"<<fail;
if(fail)
{ char in[81];
if(exp_flag==1) //Remove input expression if
temp.getline(in,81,'\n'); //output failed
return -1;
}
return 0;
}
int insert() //insert into queue
{ int ctr=0,sign=1,MinusFlag=1;
float factor;
char in[81];
info inf={ 0,0}; //INPUT is by default integer
for(int i=0;i<81&&in[i-1]!=';';i++)
{ cin.get(in[i]);
if(isspace(in[i]))i--;
}
for(i=0;in[i]!=';';i++)
{
if(symb(in[i]))
{
if(in[i]=='-'&&MinusFlag)
//If operator is unary
{ sign=-1; //minus, change sign of
inf.flag=0; //factor, set flag as
continue; //integer, and continue
}
else if(symb(in[i])&&symb(in[i+1]))
if(in[i+1]!='('&&in[i+1]!='-'&&in[i]!=')')
{ cout<<"Error!! too many operators!!!";
return -1;
}
else
sign=1;
if(in[i]=='(')
{ ctr++;
if(inf.flag!=2&&i!=0) //If there is no symbol
{ inf.el.sym='*'; //before '(', then
inf.flag=2; //multiply by default
expr.push(inf);
}
}
else if(in[i]==')')
ctr--;
if(in[i]=='-') MinusFlag=1;
inf.flag=2; //INPUT is a symbol(operator)
inf.el.sym=in[i];
expr.push(inf);
}
else if(isdigit(in[i]))
{ if(symb(in[i-1])||i==0)
{ inf.flag=0; //reset flag
inf.el.fval=0.0; //reset el
inf.el.ival=(int)(in[i]-'0')*sign;
}
else if(inf.flag)
{ factor/=10; //decrement the place value
//of last digit
inf.el.fval+=(in[i]-'0')*factor*sign;
}
else
inf.el.ival=10*inf.el.ival+(int)(in[i]-'0')*sign;
if(symb(in[i+1])||in[i+1]==';')
expr.push(inf);
}
else if(in[i]=='.')
{ inf.el.fval=(float)inf.el.ival;
inf.flag=1; //INPUT is float type
factor=1; //Reset the place value
//of last digit added
if(symb(in[i+1])||in[i+1]==';')
expr.push(inf);
}
}
if(ctr>0)
while(ctr)
{ info inf={')',2};
expr.push(inf);
ctr--;
}
else if(ctr<0)
{ cout<<"Error!!! More right paranthesis!!!";
return -1;
}
temp.write(in,(i-1));
temp<<'\n';
exp_flag=1;
return 0;
}
char symb(char c)
{ switch(c)
{ case '^':return 9;
case '/':return 8;
case '*':return 8;
case '+':return 7;
case '-':return 7;
case '(':return -1;
case ')':return 1;
default :return 0;
}
}
void display(Queue exp)
{ info inf={0,0};
while(inf.flag!=-5)
{ inf=exp.pop();
switch(inf.flag)
{ case 0 :cout<<"\nInteger : "<<inf.el.ival;break;
case 1 :cout<<"\nFloat : "<<inf.el.fval;break;
case 2 :cout<<"\nOperator: "<<inf.el.sym;break;
case -5:cout<<"\nEnd ofExpression";break;
default:cout<<"\nError in output";
}
}
}
void post_convert()
{ Queue temp;
Stack symbols;
info psym,pexp={'(',2};
symbols.push(pexp);
while(pexp.flag!=-5)
{ pexp=expr.pop();
if(pexp.flag==2)
{ psym=symbols.peek();
while((symb(psym.el.sym)>symb(pexp.el.sym))
&&pexp.el.sym!='(')
{ psym=symbols.pop(); //Push all operators of
temp.push(psym); //greater precedence
psym=symbols.peek(); //into expr
}
if(pexp.el.sym==')') //If the symbol is ')' , then
symbols.pop(); //remove '(' from the symbols
else //Else push the symbol into
symbols.push(pexp); //the symbols stack
}
else if(pexp.flag==-5)
{ psym=symbols.pop();
while(psym.el.sym!='(')
{ temp.push(psym);
psym=symbols.pop();
}
}
else
temp.push(pexp);
}
expr=temp;
}
int evaluate()
{ Stack eval;
info pexp,pnum,op1,op2,res;
int ctr=0;
pexp=expr.pop();
do
{ ctr++;
if(pexp.flag==1||pexp.flag==0) //if element is a number
eval.push(pexp); //push into stack
else if(pexp.flag==2)
{ op2=eval.pop();
op1=eval.pop();
if(op1.flag||op2.flag) //if op1 or op2 is float type
res.flag=1; //the result is float
else if(op1.flag==-5) //else if there is no element
cout<<"Too less operands"; //in stack, display error
else //else
res.flag=0; //the result is int type
switch(pexp.el.sym)
{ case '+' :if(res.flag)
res.el.fval=
(op1.flag?op1.el.fval:op1.el.ival)+
(op2.flag?op2.el.fval:op2.el.ival);
else
res.el.ival=
(op1.flag?op1.el.fval:op1.el.ival)+
(op2.flag?op2.el.fval:op2.el.ival);
break;
case '-' :if(res.flag)
res.el.fval=
(op1.flag?op1.el.fval:op1.el.ival)-
(op2.flag?op2.el.fval:op2.el.ival);
else
res.el.ival=
(op1.flag?op1.el.fval:op1.el.ival)-
(op2.flag?op2.el.fval:op2.el.ival);
break;
case '*' :if(res.flag)
res.el.fval=
(op1.flag?op1.el.fval:op1.el.ival)*
(op2.flag?op2.el.fval:op2.el.ival);
else
res.el.ival=
(op1.flag?op1.el.fval:op1.el.ival)*
(op2.flag?op2.el.fval:op2.el.ival);
break;
case '/' :if(res.flag)
res.el.fval=
(op1.flag?op1.el.fval:op1.el.ival)/
(op2.flag?op2.el.fval:op2.el.ival);
else
res.el.ival=
(op1.flag?op1.el.fval:op1.el.ival)/
(op2.flag?op2.el.fval:op2.el.ival);
break;
default :cout<<"\nError!!in eval"<<pexp.el.sym;return-1;
}
eval.push(res);
}
pexp=expr.pop();
}while(pexp.flag!=-5);
res=eval.pop();
op1=eval.pop();
if(op1.flag!=-5)
return -1;
cout<<"OUTPUT of expressions in the last line : "
<<(res.flag?res.el.fval:res.el.ival)<<'\n';
temp<<'$'<<'#';
temp.write((char*) &res,sizeof res);
return 0;
}
/*******************************End of Definitions****************************/
/***********************Definition of Queue class functions*******************/
void Queue::push(info n)
{ if(front==NULL)
front=rear=new node;
else
{ rear->next=new node;
rear=rear->next;
}
if(rear==NULL)
cout<<"Error cannot insert in Q";
rear->inf=n;
}
info Queue::pop()
{ if(front==NULL)
{ info temp={0,-5};
return temp;
}
info temp=front->inf;
node *temptr=front;
if(front==rear) front=rear=NULL;
else
front=front->next;
delete temptr;
return temp;
}
/*******************************End of Definitions****************************/
/*********************Function Definitions of Stack Class**********************/
void Stack::push(info n)
{ node* temp=new node;
if(temp==NULL)
{ cout<<"Cannot insert into stack!!!";
return;
}
temp->inf=n;
temp->next=top;
top=temp;
}
info Stack::pop()
{ if(top==NULL)
{ info temp={0,-5};
return temp;
}
info n=top->inf;
node* temp=top;
top=top->next;
delete temp;
return n;
}
/********************************End of Definitions***************************/