home *** CD-ROM | disk | FTP | other *** search
- ===========================================================================
- BBS: The Abacus * HST/DS * Potterville, MI
- Date: 06-07-93 (03:21) Number: 88
- From: BOB STOUT Refer#: 121
- To: BYTES CRUNCHER Recvd: NO
- Subj: Parser Conf: (37) C++ Langua
- ---------------------------------------------------------------------------
- In a message of <Jun 05 00:29>, Bytes Cruncher (1:167/281@fidonet) writes:
-
- >I would like to know where I can find the code for a good parser to
- >evaluate mathematical expression. If you can include the code in the
- >message it would be greatly appreciated.
-
- From SNIPPETS:
-
- /*
- ** EVAL.C - A simple mathematical expression evaluator in C
- **
- ** operators supported: (
- ** )
- ** +
- ** -
- ** *
- ** /
- ** ^
- **
- ** limitations: 1 - No precedence rules are implemented.
- ** 2 - Numbers can be negated (e.g. "-13"), but not
- ** expressions (e.g. "-(13)").
- **
- ** Original Copyright 1991 by Bob Stout as part of
- ** the MicroFirm Function Library (MFL)
- **
- ** This subset* version is hereby donated to the public domain.
- **
- ** *(The MFL version adds 150 lines of code, 5 level precedence,
- ** logarithmic and transcendental operators, pi as a constant,
- ** named variables, and fully understands negation.)
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <math.h>
-
- #define NUL '\0'
-
- typedef enum {R_ERROR = -2 /* range */, ERROR /* syntax */, SUCCESS} STATUS;
-
- static char delims[] = "+-*/^)("; /* Tokens */
- static char op_stack[256]; /* Operator stack */
- static double arg_stack[256]; /* Argument stack */
- static char token[256]; /* Token buffer */
- static int op_sptr, /* op_stack pointer */
- arg_sptr, /* arg_stack pointer */
- parens, /* Nesting level */
- state = 0; /* 0 = Awaiting expression
- 1 = Awaiting operator
- */
-
- int evaluate(char *, double *);
-
- static int do_op(void);
- static int do_paren(void);
- static void push_op(char);
- static void push_arg(double);
- static STATUS pop_arg(double *);
- static STATUS pop_op(int *);
- static char *getexp(char *);
- static char *getop(char *);
- static void pack(char *);
-
- #ifdef TEST
-
- void main(int argc, char *argv[])
- {
- double val;
-
- printf("evaluate(%s) ", argv[1]);
- printf("returned %d\n", evaluate(argv[1], &val));
- printf("val = %f\n", val);
- }
-
- #endif
-
- /*
- ** Evaluate a mathematical expression
- */
-
- int evaluate(char *line, double *val)
- {
- double arg;
- char *ptr = line, *str, *endptr;
- int ercode;
-
- pack(line);
-
- while (*ptr)
- {
- switch (state)
- {
- case 0:
- if (NULL != (str = getexp(ptr)))
- {
- if ('(' == *str)
- {
- push_op(*str);
- ptr += strlen(str);
- break;
- }
-
- if (0.0 == (arg = strtod(str, &endptr)) &&
- NULL == strchr(str, '0'))
- {
- return ERROR;
- }
- push_arg(arg);
- ptr += strlen(str);
- }
- else return ERROR;
-
- state = 1;
- break;
-
- case 1:
- if (NULL == (str = getop(ptr)))
- return ERROR;
-
- if (strchr(delims, *str))
- {
- if (')' == *str)
- {
- if (SUCCESS > (ercode = do_paren()))
- return ercode;
- }
- else
- {
- push_op(*str);
- state = 0;
- }
-
- ptr += strlen(str);
- }
- else return ERROR;
-
- break;
- }
- }
-
- while (1 < arg_sptr)
- {
- if (SUCCESS > (ercode = do_op()))
- return ercode;
- }
- if (!op_sptr)
-