Answer to Question #288165 in C++ for Nica

Question #288165

Add the ability to use {} as well as () in the program, so that {(4+5)*6} / (3+4) will be a


valid expression.


3. Add a factorial operator: use a suffix ! operator to represent “factorial.” For example, the


expression 7! means 7 * 6 * 5 * 4 * 3 * 2 * 1. Make ! bind tighter than * and /; that is,


7*8! means 7* (8!) rather than (7*8)!. Begin by modifying the grammar to account for a


higher-level operator. To agree with the standard mathematical definition of factorial, let


0! evaluate to 1. Hint: The calculator functions deal with doubles, but factorial is defined


only for ints, so just for x!, assign the x to an int and calculate the factorial of that int.

1
Expert's answer
2022-01-17T09:47:49-0500
#include <iostream> //I/O 
#include <string> //string 
#include <map> // map  
#include <cctype> // isalpha(),...
#include<sstream>

using namespace std; 
map<string,double>table;
double number_value; 
string string_value; 

int no_of_errors; 
double error (const string& s);
double prim(bool get);
double term (bool get); 
double expr (bool get);

enum Token_value 
{ 
	NAME, NUMBER, END, 
	PLUS='+', MINUS='-', MUL='*', DIV='/', 
	PRINT=';', ASSIGN='=', LP='(' , RP=')',
	LF='{',RF='}',FACTOR='!'
}; 

Token_value curr_tok=PRINT; 

double error (const string& s) 
{ 
	no_of_errors++;
	cerr<<"error:"<<s<<'\n'; 
	return 1; 
} 

Token_value get_token() 
{ 
	char ch=0; 
	cin>>ch; 
	switch(ch) 
	{ 
		case 0: 
			return curr_tok=END ; 
		case ';': 
		case '*': 
		case '/': 
		case '+': 
		case '-': 
		case '(': 
		case ')': 
		case '{': 
		case '}': 
		case '!': 
		case '=': 
			return curr_tok=Token_value (ch); 
		case '0' : case '1' : case '2' : case '3' : case '4' : 
		case '5' : case '6' : case '7' : case '8' : case '9' : 
		case '.' : 
			cin.putback(ch) ; 
			cin>>number_value; 
			return curr_tok=NUMBER;	 
		default:  
			if (isalpha (ch)) 
			{ 
				cin.putback(ch); 
				cin>>string_value; 
				return curr_tok=NAME; 
			} 
		error ("bad token") ; 
		return curr_tok=PRINT; 
	}
}
double prim(bool get)
{
	if(get)get_token(); 
	switch (curr_tok) 
	{ 
		case NUMBER: 
		{ 
			double v = number_value; 
			get_token(); 
			if(curr_tok==FACTOR)
			{
				int n=v;
				if(n==0)v=1;
				else
				{
					double res=1;
					for(int i=1;i<=n;i++)
					{
						res*=i;
					}
					v=res;
				}
				get_token();
			}
			return v; 
		} 
		case NAME: 
		{ 
			double &v = table[string_value] ; 
			if (get_token() == ASSIGN) v = expr(true) ; 
			return v; 
		} 
		case MINUS:  
			return -prim(true); 
		case LP: 
 		{
			double e = expr(true) ; 
			if(curr_tok!= RP) return error (" ')' expected"); 
			get_token(); 
			return e; 
		}
		case LF: 
 		{
			double e = expr(true) ; 
			if(curr_tok!= RF) return error (" '}' expected"); 
			get_token(); 
			return e; 
		} 
		default: 
			return error ("primary expected") ; 
	} 
} 


double term (bool get) 
{ 
	double left = prim(get); 
	for(;;) 
	{
		switch (curr_tok) 
		{ 
		case MUL:
			left *= prim (true) ; 
			break; 
		case DIV: 
			if (double d = prim(true) ) 
			{
				left /= d; 
				break; 		
			} 
			return error("divide by 0"); 
		default: 
			return left; 
		}	 
	}
} 


double expr (bool get) 
{ 
	double left=term (get) ; 
	for(;;) 
	{
		switch (curr_tok) 
		{ 
		case PLUS: 
			left +=term(true) ; 
			break; 
		case MINUS: 
			left -=term(true) ; 
			break; 
		default: 
			return left; 
		} 	
	} 	
} 


istream* input ; 
int main () 
{ 
	cout<<"***You are working with calculator***";
	cout<<"\nPlease, enter an expression:";
	input= &cin; 
	table ["pi"] =3.1415926535897932385; 
	table ["e"] =2.7182818284590452354; 
	while (*input) 
	{ 	
		get_token(); 
		if (curr_tok==END) break; 
		if(curr_tok==PRINT) continue; 
			cout<<expr(false)<<'\n';
	} 
	if(input!=&cin) delete input; 
		return no_of_errors; 
}  

Need a fast expert's response?

Submit order

and get a quick answer at the best price

for any assignment or question with DETAILED EXPLANATIONS!

Comments

No comments. Be the first!

Leave a comment