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***************************/

Recommended Answers

All 4 Replies

Yes, you need to add more comments -- everywhere. First you need an explaination at the top of the program to tell us what the program is supposed to do. Even "glancing" at main() I don't know what it is trying to do.

If in doubt -- comment it.

More comments are needed to be added.

/*********************************
 * What is the title of your program?     *
 * What is the purpose of this program?*
 * Written by who?                              *
 *********************************/

// What is this union for?
union element { 
  char sym; // what is this char for?
  int ival;  // what is this integer use for?
  float fval; // what is this float variable for?
};
....
....
in main()
{
  ...
  ...
  cin.get(ch);
  while(ch!=7) // why?
  {
     exp_flag=0; // why I need this statement?
     if(ch=='=') // what happen if ch is '='?
  ...
}
commented: that was really helpful! +1

ok! i'll close this thread and repost the program after i've documented it properly!!!

421 lines of code without a comment.... i think that self explaining code is about a dozen of lines.. not 421 !!! So you are convinced that if you like these 421 lines after a year or so you will remember what the code does? :P

anyway this is an extract from Linux kernel coding style::

Chapter 5: Commenting

Comments are good, but there is also a danger of over-commenting. NEVER
try to explain HOW your code works in a comment: it's much better to
write the code so that the _working_ is obvious, and it's a waste of
time to explain badly written code.

Generally, you want your comments to tell WHAT your code does, not HOW.
Also, try to avoid putting comments inside a function body: if the
function is so complex that you need to separately comment parts of it,
you should probably go back to chapter 4 for a while. You can make
small comments to note or warn about something particularly clever (or
ugly), but try to avoid excess. Instead, put the comments at the head
of the function, telling people what it does, and possibly WHY it does
it.

-nicolas
merry christmas to you all :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.