Here is the full code..
This is a clculator example from the c++ programming language by Bjarne Stroustrup
what I posted is part of the parser
Code:
/****************************************HEADERS***************************************************/
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <cctype>
using namespace std;
/****************************************GLOBAL VARIABLES****************************************/
enum Token_value
{
NAME, NUMBER, END,
PLUS='+', MINUS='-', MUL='*', DIV='/',
PRINT=';', ASSIGN='=', LP='(', RP=')',
};
struct LineCounter
{
LineCounter(): line(0) {}
unsigned long current() { return line; }
void new_line() { ++line; }
private:
unsigned long line;
};
LineCounter line_count;
Token_value curr_tok = PRINT;
double number_value;
string string_value;
map<string,double> table;
map<string,string> expression;
int no_of_errors;
istream* input; //pointer to input stream
/****************************************FUNCTIONS CALLS*****************************************/
double expr(bool get);
double term(bool get);
double prim(bool get);
double create();
double error(const string& msg);
Token_value get_token();
/*****************************************MAIN******************************************************/
int main(int argc, char* argv[])
{
switch (argc)
{
case 1 : // read from standard input
input = &cin;
break;
case 2 :
input = new istringstream(argv[1]); // read argument string
break;
default :
error ("Too many arguments");
return 1;
}
table["pi"] = 3.1415926535897932385; // insert predefined names
table["e"] = 2.7182818284590452354;
while (*input)
{
cout << "Enter a mathematical expression : (Type 'E' to exit)" << endl;
get_token();
if (curr_tok == END) break;
if (curr_tok == PRINT) continue;
cout << expr(false) <<endl;
}
if (input != &cin) delete input;
return no_of_errors;
}
/*****************************************OTHER FUNCTIONS*****************************************/
double expr(bool get) // add and substract
{
double left = term(get);
for(;;)
switch (curr_tok)
{
case PLUS :
left += term(true);
break;
case MINUS :
left -= term(true);
break;
default :
return left;
}
}
double term(bool get) // multiply and divide
{
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 prim(bool get) // handle primaries
{
if (get) get_token();
switch (curr_tok)
{
case NUMBER : // floating point constant
{
double v = number_value;
get_token();
return v;
}
case NAME :
{
string str = "new";
if (string_value == str) return create();
else
{
double &v = table[string_value];
if (get_token() == ASSIGN) v = expr(true);
return v;
}
}
case MINUS : // unary minus
return -prim(true);
case LP :
{
double e = expr(true);
if (curr_tok != RP) return error("')' expected");
get_token(); //eat ')'
return e;
}
default :
return error("primary expected");
}
}
Token_value get_token()
{
char ch = 0;
do { // skip whitespace except '\n'
if(!cin.get(ch)) return curr_tok = END;
}while (ch != '\n' && isspace(ch));
switch (ch)
{
case 0 : case 'E':
return curr_tok=END;
case ';' : return curr_tok = PRINT;
case '\n' : line_count.new_line();
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: // NAME, NAME =, or error
if (isalpha(ch))
{
string_value = ch;
while (cin.get(ch) && isalnum(ch)) string_value.push_back(ch);
cin.putback(ch);
return curr_tok = NAME;
}
error("Bad Token");
return curr_tok = PRINT;
}
}
double create() //Dont mind this part, im trying to improve the calc
{ //by ading the possibility to enter user functions..
int number = 0;
double ref = 0.0;
string temp, name;
cout << "Enter a name for the expression : " << endl;
cin >> name;
cout << "Enter the number of variables in expression :" << endl;
cin >> number;
for(int j = 0, i =1; j < number; j++, i++)
{
cout << "Enter a name for variable #" << i<< endl;
cin >> temp;
cout << "Enter a value for that variable :" << endl;
cin >> ref;
table[temp] = ref;
}
cout << "Enter an expression :" << endl;
cin >> temp;
expression[name] = temp;
curr_tok = PRINT;
return 1;
}
double error(const string &msg)
{
no_of_errors++;
cerr << "error : " << msg << " at line : " << line_count.current() << endl;
return 1;
}