Aug 4, 2015 at 1:53pm UTC
#include <iostream>
#include <vector>
#include <conio.h>
#include <string>
#include <sstream>
enum tokentype {TT_NUMBER, TT_PLUS, TT_MINUS, TT_MUL, TT_DIV, TT_LPAREN, TT_RPAREN, NILL};
std::string DoubleToString(double dbl)
{
std::ostringstream strs;
strs << dbl;
std::string str = strs.str();
return str;
}
double stringToDouble(std::string s)
{
double d;
std::stringstream ss(s);
ss >> d;
return d;
}
class Token
{
public:
std::string content;
tokentype type;
};
class Parser
{
private:
std::vector<Token> tokens;
std::vector <Token> cutrange(std::vector<Token>&, int, int);
std::vector<Token> getparens(std::vector<Token>);
void scan();
std::string calc(std::vector<Token>&);
public:
std::string root;
Parser(std::string);
std::string result;
};
std::vector<Token> Parser::cutrange(std::vector<Token> &source, int begin, int end)
{
std::vector<Token> buf;
int counter = begin;
while (counter <= end)
{
buf.push_back(source[counter]);
counter++;
}
counter = 0;
while (counter <= end-begin)
{
source.erase(source.begin() + begin);
counter++;
}
return buf;
}
std::vector<Token> Parser::getparens(std::vector<Token> tokenstring)
{
int counter = 0;
int firstpos;
int lastpos;
while (counter <= tokenstring.size() - 1)
{
if (tokenstring[counter].type == TT_LPAREN)
{
firstpos = counter;
}
if (tokenstring[counter].type == TT_RPAREN)
{
lastpos = counter;
}
counter++;
}
if (lastpos != NULL && firstpos != NULL)
{
tokenstring.erase(tokenstring.begin() + firstpos);
tokenstring.erase(tokenstring.begin() + lastpos);
std::vector<Token> buf = cutrange(tokenstring, firstpos, lastpos - 1);
std::string res = calc(buf);
counter = 0;
tokenstring.insert(tokenstring.begin() + (firstpos + 1 + counter), buf[counter]);
}
return tokenstring;
}
Parser::Parser(std::string calculation)
{
root = calculation;
scan();
result = calc(tokens);
}
void Parser::scan()
{
std::string delbuf;
int lastpos = 0;
std::string buf;
int counter = 0;
tokentype currenttype;
tokentype lasttype = NILL;
Token tbuf;
for (int i = 0; i < strlen(root.c_str()); i++)
{
delbuf = root.substr(i, 1);
if (delbuf == " ")
{
root.erase(i, 1);
}
}
do
{
buf = root.substr(counter, 1);
if (buf == "0")
{
currenttype = TT_NUMBER;
}
if (buf == "1")
{
currenttype = TT_NUMBER;
}
if (buf == "2")
{
currenttype = TT_NUMBER;
}
if (buf == "3")
{
currenttype = TT_NUMBER;
}
if (buf == "4")
{
currenttype = TT_NUMBER;
}
if (buf == "5")
{
currenttype = TT_NUMBER;
}
if (buf == "6")
{
currenttype = TT_NUMBER;
}
if (buf == "7")
{
currenttype = TT_NUMBER;
}
if (buf == "8")
{
currenttype = TT_NUMBER;
}
if (buf == "9")
{
currenttype = TT_NUMBER;
}
if (buf == ".")
{
currenttype = TT_NUMBER;
}
if (buf == "+")
{
currenttype = TT_PLUS;
}
if (buf == "-")
{
currenttype = TT_MINUS;
}
if (buf == "*")
{
currenttype = TT_MUL;
}
if (buf == "/")
{
currenttype = TT_DIV;
}
if (buf == "(")
{
currenttype = TT_LPAREN;
}
if (buf == ")")
{
currenttype = TT_RPAREN;
}
if (currenttype != lasttype)
{
tbuf.content = root.substr(lastpos, (counter - lastpos));
tbuf.type = lasttype;
lastpos = counter;
tokens.push_back(tbuf);
}
lasttype = currenttype;
counter++;
} while (counter <= strlen(root.c_str()) - 1);
tbuf.content = root.substr(lastpos, strlen(root.c_str()) - lastpos);
tbuf.type = currenttype;
tokens.push_back(tbuf);
tokens.erase(tokens.begin() + 0);
for (int a = 0; a <= tokens.size() - 1; a++)
{
std::cout << tokens[a].content << " " << tokens[a].type << std::endl;
}
}
std::string Parser::calc(std::vector<Token> &tokenstring)
{
std::cout << "calc launched!" << std::endl;
Token Buftoken;
tokenstring = getparens(tokenstring);
for (int a = 0; a <= tokenstring.size()-1; a++)
{
if (tokenstring[a].type == TT_MUL || tokenstring[a].type == TT_DIV)
{
if (tokenstring[a].type == TT_MUL)
{
double buffer = stringToDouble(tokenstring[a - 1].content) * stringToDouble(tokenstring[a + 1].content);
cutrange(tokenstring, a - 1, a + 1);
Buftoken.content = DoubleToString(buffer);
Buftoken.type = TT_NUMBER;
tokenstring.insert(tokenstring.begin() + (a - 1), Buftoken);
}
if (tokenstring[a].type == TT_DIV)
{
double buffer = stringToDouble(tokenstring[a - 1].content) / stringToDouble(tokenstring[a + 1].content);
cutrange(tokenstring, a - 1, a + 1);
Buftoken.content = DoubleToString(buffer);
Buftoken.type = TT_NUMBER;
tokenstring.insert(tokenstring.begin() + (a - 1), Buftoken);
}
}
}
for (int a = 0; a <= tokenstring.size() - 1; a++)
{
if (tokenstring[a].type == TT_PLUS || tokenstring[a].type == TT_MINUS)
{
if (tokenstring[a].type == TT_PLUS)
{
double buffer = stringToDouble(tokenstring[a - 1].content) + stringToDouble(tokenstring[a + 1].content);
cutrange(tokenstring, a - 1, a + 1);
Buftoken.content = DoubleToString(buffer);
Buftoken.type = TT_NUMBER;
tokenstring.insert(tokenstring.begin() + (a - 1), Buftoken);
}
if (tokenstring[a].type == TT_MINUS)
{
double buffer = stringToDouble(tokenstring[a - 1].content) - stringToDouble(tokenstring[a + 1].content);
cutrange(tokenstring, a - 1, a + 1);
Buftoken.content = DoubleToString(buffer);
Buftoken.type = TT_NUMBER;
tokenstring.insert(tokenstring.begin() + (a - 1), Buftoken);
}
}
}
return tokenstring[0].content;
}
int main()
{
Parser calc("(3.1 + 39) / 22");
std::cout << calc.result << std::endl;
_getch();
}
This should be a math parser. Sorry for writing it into one single file, I forgot to divide it into headers and cpps. The Program output is pretty strange, it says that calc.result = "(".
Anybody got an idea what the error is?