home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD2.mdf
/
c
/
library
/
mslang
/
cp1
/
eval1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-10
|
5KB
|
157 lines
===========================================================================
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)