i want my parse.ccp to calculate an expression which will have an interger,floating point, binary and hexacimal values like.
e.g
when i include this expression it works :
radius = 456 sin( pi / 2 ) + pi * radius *radius + 4500
but when i include this it will give me error:
radius = 456 sin( pi / 2 ) + pi * radius *radius + 0x1F - 1100b
this is my parse.cpp file
#include "parser.h"
const int getrandom (const int x)
{
if (x <= 0)
return 0;
double r = static_cast<double> (std::rand () % RAND_MAX) / (static_cast<double> (RAND_MAX) + 1.0);
return floor (r * x);
}
const int roll (const int howmany, const int die)
{
int count;
int total = 0;
for (count = 0; count < howmany; ++count)
total += getrandom (die) + 1;
return total;
}
const bool percent (const int prob)
{
if (prob <= 0)
return false;
if (prob >= 100)
return true;
return getrandom (100) > (100 - prob);
}
static int initRandom ()
{
srand (time (NULL));
#ifndef WIN32
srand48 (time (NULL));
#endif
return 0;
}
static int someNumber = initRandom ();
double DoInt (double arg)
{
return (int) arg; }
double toInteger(char c)
{
if (c >= '0' && c <= '9') return c -'0';
if (c >= 'a' && c <= 'f') return c -'a' + 0xa;
if (c >= 'A' && c <= 'F') return c -'A' + 0xa;
double noDigit = 0xf + 1;
return noDigit;
}
double DoRandom (double arg)
{
return getrandom (static_cast <int> (arg)); }
double DoPercent (double arg)
{
if (percent (static_cast <int> (arg))) return 1.0;
else
return 0.0;
}
const double DoMin (const double arg1, const double arg2)
{
return (arg1 < arg2 ? arg1 : arg2);
}
const double DoMax (const double arg1, const double arg2)
{
return (arg1 > arg2 ? arg1 : arg2);
}
const double DoFmod (const double arg1, const double arg2)
{
if (arg2 == 0.0)
throw std::runtime_error ("Divide by zero in mod");
return fmod (arg1, arg2);
}
const double DoPow (const double arg1, const double arg2)
{
return pow (arg1, arg2);
}
const double DoRoll (const double arg1, const double arg2)
{
return roll (static_cast <int> (arg1), static_cast <int> (arg2));
}
const double DoIf (const double arg1, const double arg2, const double arg3)
{
if (arg1 != 0.0)
return arg2;
else
return arg3;
}
typedef double (*OneArgFunction) (double arg);
typedef const double (*TwoArgFunction) (const double arg1, const double arg2);
typedef const double (*ThreeArgFunction) (const double arg1, const double arg2, const double arg3);
static std::map<std::string, OneArgFunction> OneArgumentFunctions;
static std::map<std::string, TwoArgFunction> TwoArgumentFunctions;
static std::map<std::string, ThreeArgFunction> ThreeArgumentFunctions;
#define STD_FUNCTION(arg) OneArgumentFunctions [#arg] = arg
static int LoadOneArgumentFunctions ()
{
OneArgumentFunctions ["abs"] = fabs;
STD_FUNCTION (acos);
STD_FUNCTION (asin);
STD_FUNCTION (atan);
#ifndef WIN32 // doesn't seem to exist under Visual C++ 6
STD_FUNCTION (atanh);
#endif
STD_FUNCTION (cos);
STD_FUNCTION (exp);
STD_FUNCTION (exp);
STD_FUNCTION (log);
STD_FUNCTION (log10);
STD_FUNCTION (sin);
STD_FUNCTION (sqrt);
STD_FUNCTION (tan);
OneArgumentFunctions ["int"] = DoInt;
OneArgumentFunctions ["rand"] = DoRandom;
OneArgumentFunctions ["rand"] = DoRandom;
OneArgumentFunctions ["percent"] = DoPercent;
return 0;
}
static int LoadTwoArgumentFunctions ()
{
TwoArgumentFunctions ["min"] = DoMin;
TwoArgumentFunctions ["max"] = DoMax;
TwoArgumentFunctions ["mod"] = DoFmod;
TwoArgumentFunctions ["pow"] = DoPow; TwoArgumentFunctions ["roll"] = DoRoll; return 0;
}
static int LoadThreeArgumentFunctions ()
{
ThreeArgumentFunctions ["if"] = DoIf;
return 0;
}
const Parser::TokenType Parser::GetToken (const bool ignoreSign)
{
word_.erase (0, std::string::npos);
while (*pWord_ && isspace (*pWord_))
++pWord_;
pWordStart_ = pWord_;
if (*pWord_ == 0 && type_ == END) throw std::runtime_error ("Unexpected end of expression.");
unsigned char cFirstCharacter = *pWord_;
if (cFirstCharacter == 0) {
word_ = "<end of expression>";
return type_ = END;
}
unsigned char cNextCharacter = *(pWord_ + 1);
if ((!ignoreSign &&
(cFirstCharacter == '+' || cFirstCharacter == '-') &&
(isdigit (cNextCharacter) || cNextCharacter == '.')
)
|| isdigit (cFirstCharacter)
|| (cFirstCharacter == '.' && isdigit (cNextCharacter)) )
{
if ((cFirstCharacter == '+' || cFirstCharacter == '-'))
pWord_++;
while (isdigit (*pWord_) || *pWord_ == '.')
pWord_++;
if (*pWord_ == 'e' || *pWord_ == 'E')
{
pWord_++; if ((*pWord_ == '+' || *pWord_ == '-'))
pWord_++; while (isdigit (*pWord_)) pWord_++;
}
word_ = std::string (pWordStart_, pWord_ - pWordStart_);
std::istringstream is (word_);
is >> value_;
if (is.fail () && !is.eof ())
throw std::runtime_error ("Bad numeric literal: " + word_);
return type_ = NUMBER;
}
if (cNextCharacter == '=')
{
switch (cFirstCharacter)
{
case '=': type_ = EQ; break;
case '<': type_ = LE; break;
case '>': type_ = GE; break;
case '!': type_ = NE; break;
case '+': type_ = ASSIGN_ADD; break;
case '-': type_ = ASSIGN_SUB; break;
case '*': type_ = ASSIGN_MUL; break;
case '/': type_ = ASSIGN_DIV; break;
default: type_ = NONE; break;
}
if (type_ != NONE)
{
word_ = std::string (pWordStart_, 2);
pWord_ += 2; return type_;
} }
switch (cFirstCharacter)
{
case '&': if (cNextCharacter == '&') {
word_ = std::string (pWordStart_, 2);
pWord_ += 2; return type_ = AND;
}
break;
case '|': if (cNextCharacter == '|') {
word_ = std::string (pWordStart_, 2);
pWord_ += 2; return type_ = OR;
}
break;
case '=':
case '<':
case '>':
case '+':
case '-':
case '/':
case '*':
case '(':
case ')':
case ',':
case '!':
word_ = std::string (pWordStart_, 1);
++pWord_; return type_ = TokenType (cFirstCharacter);
}
if (!isalpha (cFirstCharacter))
{
if (cFirstCharacter < ' ')
{
std::ostringstream s;
s << "Unexpected character (decimal " << int (cFirstCharacter) << ")";
throw std::runtime_error (s.str ());
}
else
throw std::runtime_error ("Unexpected character: " + std::string (1, cFirstCharacter));
}
while (isalnum (*pWord_) || *pWord_ == '_')
++pWord_;
word_ = std::string (pWordStart_, pWord_ - pWordStart_);
return type_ = NAME;
}
static int doLoadOneArgumentFunctions = LoadOneArgumentFunctions ();
static int doLoadTwoArgumentFunctions = LoadTwoArgumentFunctions ();
static int doLoadThreeArgumentFunctions = LoadThreeArgumentFunctions ();
const double Parser::Primary (const bool get) {
if (get)
GetToken ();
switch (type_)
{
case NUMBER:
{
double v = value_;
GetToken (true); return v;
}
case NAME:
{
std::string word = word_;
GetToken (true);
if (type_ == LHPAREN)
{
std::map<std::string, OneArgFunction>::const_iterator si;
si = OneArgumentFunctions.find (word);
if (si != OneArgumentFunctions.end ())
{
double v = Expression (true); CheckToken (RHPAREN);
GetToken (true); return si->second (v); }
std::map<std::string, TwoArgFunction>::const_iterator di;
di = TwoArgumentFunctions.find (word);
if (di != TwoArgumentFunctions.end ())
{
double v1 = Expression (true); CheckToken (COMMA);
double v2 = Expression (true); CheckToken (RHPAREN);
GetToken (true); return di->second (v1, v2); }
std::map<std::string, ThreeArgFunction>::const_iterator ti;
ti = ThreeArgumentFunctions.find (word);
if (ti != ThreeArgumentFunctions.end ())
{
double v1 = Expression (true); CheckToken (COMMA);
double v2 = Expression (true); CheckToken (COMMA);
double v3 = Expression (true); CheckToken (RHPAREN);
GetToken (true); return ti->second (v1, v2, v3); }
throw std::runtime_error ("Function '" + word + "' not implemented.");
}
double & v = symbols_ [word]; switch (type_)
{
case ASSIGN: v = Expression (true); break;
case ASSIGN_ADD: v += Expression (true); break;
case ASSIGN_SUB: v -= Expression (true); break;
case ASSIGN_MUL: v *= Expression (true); break;
case ASSIGN_DIV:
{
double d = Expression (true);
if (d == 0.0)
throw std::runtime_error ("Divide by zero");
v /= d;
break; } default: break; } return v; }
case MINUS: return - Primary (true);
case NOT: return (Primary (true) == 0.0) ? 1.0 : 0.0;;
case LHPAREN:
{
double v = CommaList (true); CheckToken (RHPAREN);
GetToken (true); return v;
}
default:
throw std::runtime_error ("Unexpected token: " + word_);
}
}
const double Parser::Term (const bool get) {
double left = Primary (get);
while (true)
{
switch (type_)
{
case MULTIPLY:
left *= Primary (true); break;
case DIVIDE:
{
double d = Primary (true);
if (d == 0.0)
throw std::runtime_error ("Divide by zero");
left /= d;
break;
}
default: return left;
} } }
const double Parser::AddSubtract (const bool get) {
double left = Term (get);
while (true)
{
switch (type_)
{
case PLUS: left += Term (true); break;
case MINUS: left -= Term (true); break;
default: return left;
} } }
const double Parser::Comparison (const bool get) {
double left = AddSubtract (get);
while (true)
{
switch (type_)
{
case LT: left = left < AddSubtract (true) ? 1.0 : 0.0; break;
case GT: left = left > AddSubtract (true) ? 1.0 : 0.0; break;
case LE: left = left <= AddSubtract (true) ? 1.0 : 0.0; break;
case GE: left = left >= AddSubtract (true) ? 1.0 : 0.0; break;
case EQ: left = left == AddSubtract (true) ? 1.0 : 0.0; break;
case NE: left = left != AddSubtract (true) ? 1.0 : 0.0; break;
default: return left;
} } }
const double Parser::Expression (const bool get) {
double left = Comparison (get);
while (true)
{
switch (type_)
{
case AND:
{
double d = Comparison (true); left = (left != 0.0) && (d != 0.0);
}
break;
case OR:
{
double d = Comparison (true); left = (left != 0.0) || (d != 0.0);
}
break;
default: return left;
} } }
const double Parser::CommaList (const bool get) {
double left = Expression (get);
while (true)
{
switch (type_)
{
case COMMA: left = Expression (true); break; default: return left;
} } }
const double Parser::Evaluate () {
pWord_ = program_.c_str ();
type_ = NONE;
double v = CommaList (true);
if (type_ != END)
throw std::runtime_error ("Unexpected text at end of expression: " + std::string (pWordStart_));
return v;
}
const double Parser::Evaluate (const std::string & program) {
program_ = program;
return Evaluate ();
}
<
this is my main.cpp
<pre>#include "parser.h"
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
static const std::string SPACES = " \t\r\n";
const std::string trim (const std::string & sInput, const std::string & t = SPACES)
{
std::string s = sInput;
std::string::size_type i = s.find_last_not_of (t);
if (i == std::string::npos)
return "";
else
return s.erase (i + 1).erase (0, sInput.find_first_not_of (t)) ;
}
const std::string removeBackspaces (const std::string & sInput)
{
std::string s = sInput;
std::string::size_type i;
while ((i = s.find ('\b')) != std::string::npos)
if (i == 0)
s.erase (0, 1); else
s.erase (i - 1, 2); return s;
}
int main ()
{
string inputLine;
ifstream file ("input.txt");
ofstream file1;
file1.open("output.txt");
while (std::getline (file, inputLine))
{
if( strncmp( "----", inputLine.c_str(), 4 ) == 0 )
continue;
inputLine = trim (removeBackspaces (inputLine));
Parser p (inputLine);
p ["abc"] = 42;
double value = p.Evaluate ();
file1 <<std::cout << "Result = " << value << std::endl;
double abc = p ["abc"];
file1<<std::cout<<"----------------------"<<endl;
} }
please guys help as this assignment is killing me.
this is my example in the input file
----
radius = 456
sin( pi / 2 ) + pi * radius *radius + 0x1F - 1100b
----
10 * (20 +45)
----
2+3
What I have tried:
i have write a parse.cpp to calculate the expressions in the text.cpp.