// saved from url
// http://www-cs.canisius.edu/PL_TUTORIALS/C++/EXAMPLES/MRD/SRC/expressions.c -->
//------------------------------------expressions.c--------------------------
#include
#include
#include
#include "expressions.h"
void arithparser::tokenize (char *string, double lookup (char *))
{
char ch, lastch;
int n=0, k;
int token=0;
char valstring[100];
while (1) {
/* skip over white space */
while ((ch = string[n]) && string[n] == ' ') n++;
if (!ch) break;
if (ch == '(') {
tokens[token].type = '(';
tokens[token].value = 0;
n++;
}
else if (ch == ')') {
tokens[token].type = ')';
tokens[token].value = 0;
n++;
}
else if (ch == '+') {
tokens[token].type = 'o';
tokens[token].value = 1.0;
n++;
}
else if (ch == '-') {
tokens[token].type = 'o';
tokens[token].value = 2.0;
n++;
}
else if (ch == '*') {
tokens[token].type = 'o';
tokens[token].value = 3.0;
n++;
}
else if (ch == '/') {
tokens[token].type = 'o';
tokens[token].value = 4.0;
n++;
}
else if (isalpha(ch)) {
tokens[token].type = 'n';
valstring[0] = ch;
n++;
k = 1;
while (1) {
ch = string[n];
if (isalpha(ch) || isdigit(ch)) {
valstring[k++] = ch;
n++;
continue;
}
break;
}
valstring[k] = 0;
tokens[token].value = lookup (valstring);
}
else if (isdigit(ch)) {
tokens[token].type = 'n';
/* continue to accumulate numerical stuff */
k = 0;
ch = ' ';
while (1) {
lastch = ch;
ch = string[n];
if ((ch == '+' || ch == '-') && lastch == 'e') {
valstring[k++] = ch;
n++;
continue;
}
if (isdigit(ch) || ch == '.' || ch == 'e') {
valstring[k++] = ch;
n++;
continue;
}
break;
}
valstring[k] = 0;
tokens[token].value = atof (valstring);
}
token++;
}
tokens[token].type = 'z';
}
double arithparser::perform (double operand1, double opcode, double operand2)
{
if (opcode == 1.0)
return operand1 + operand2;
if (opcode == 2.0)
return operand1 - operand2;
if (opcode == 3.0)
return operand1 * operand2;
if (opcode == 4.0)
return operand1 / operand2;
}
double arithparser::parseval (int *tptr)
{
double currentvalue = 0.0;
double opcode, operand2;
if (tokens[*tptr].type == 'z')
return 0;
currentvalue = nextoperand (tptr);
(*tptr)++;
while (1) {
if (tokens[*tptr].type == ')' || tokens[*tptr].type == 'z') break;
opcode = tokens[*tptr].value;
(*tptr)++;
operand2 = nextoperand (tptr);
(*tptr)++;
currentvalue = perform (currentvalue, opcode, operand2);
}
return currentvalue;
}
double arithparser::nextoperand (int *tptr)
{
if (tokens[*tptr].type == '(') {
(*tptr)++;
return parseval (tptr);
}
else
return tokens[*tptr].value;
}
double arithparser::parse (char *string, double lookup(char *))
{
tokenize (string, lookup);
tokenpointer = 0;
return (parseval(&tokenpointer));
}