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.
#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;
}
Comments
Leave a comment