// saved from url // http://www-cs.canisius.edu/PL_TUTORIALS/C++/EXAMPLES/MRD/SRC/expressions.c --> //------------------------------------expressions.c-------------------------- #include <stdio.h> #include <ctype.h> #include <stdlib.h> #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)); } 1