+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <assert.h>
-
-#define NDEBUG
-
-#define BUFSIZE 1024
-
-#define bail(arg...) do { fprintf(stderr, ##arg); exit(EXIT_FAILURE); } while (0)
-
-char *arg;
-
-int istack[BUFSIZE];
-char opstack[BUFSIZE];
-int istackp,opstackp;
-
-#ifdef NDEBUG
-#define dump(x)
-#else
-static void dump(char *pref)
-{
-int i;
- fprintf(stderr,"%s: i[",pref);
- for (i=0;i<istackp;i++) {
- if (i) fputc(',',stderr);
- fprintf(stderr,"%d",istack[i]);
- }
- fprintf(stderr,"],op=[");
- for (i=0;i<opstackp;i++) fputc(opstack[i],stderr);
- fprintf(stderr,"]\n");
-}
-#endif
-
-static char lex(int *ip)
-{
-char c;
-long l;
-
- while (isspace(*arg)) arg++;
- switch (*arg) {
- case 0: case '+': case '-': case '*': case '/': case '(': case ')':
- c=*arg;
- if (c) arg++;
- return(c);
- case '0' ... '9':
- l=strtol(arg,&arg,10);
- *ip=l;
- return 'n';
- default:
- bail("Invalid characted in string: %s\n",arg);
- }
-}
-
-static int oppri(char op)
-{
- switch (op) {
- case 0: return(0);
- case '+': case '-': return (10);
- case '*': case '/': return (20);
- case '(': return (2);
- case ')': return (5);
- default: assert(0);
- }
-}
-
-static void evalit(void)
-{
- dump("evalit()");
- assert(opstackp); opstackp--;
- if (istackp<2)
- if (opstack[opstackp]!='(') bail("2 arguments for operator '%c' required!\n",opstack[opstackp]);
- else bail("Stray '('!\n");
- istackp--;
- switch (opstack[opstackp]) {
- case '+': istack[istackp-1]+=istack[istackp]; break;
- case '-': istack[istackp-1]-=istack[istackp]; break;
- case '*': istack[istackp-1]*=istack[istackp]; break;
- case '/':
- if (!istack[istackp]) bail("Division of %d by zero not supported!\n",istack[istackp-1]);
- istack[istackp-1]/=istack[istackp];
- break;
- }
-}
-
-static void pushop(char op)
-{
-int mypri=oppri(op);
- while (opstackp && op!='(' && oppri(opstack[opstackp-1])>=mypri)
- evalit();
- if (!op) return;
- if (op==')') {
- if (!opstackp || opstack[opstackp-1]!='(')
- bail("Not enough content for brackets-inside space!\n");
- opstackp--;
- return;
- }
- if (opstackp>=BUFSIZE) bail("Too many operators (%d is max)!\n",BUFSIZE);
- opstack[opstackp++]=op;
-}
-
-static void process(void)
-{
-char lastop,op;
-int curi;
-
- istackp=opstackp=0;
- for (lastop=0;;lastop=op) switch (op=lex(&curi)) {
- case 'n':
- if (lastop=='n') bail("Two successive numbers not permitted!\n");
- if (istackp>=BUFSIZE) bail("Too many operators (%d is max)!\n",BUFSIZE);
- istack[istackp++]=curi;
- break;
- case '(':
- if (lastop=='n') bail("Open-bracket not permitted after number!\n");
- pushop(op);
- break;
- case '+': case '-': case '*': case '/': case ')': pushop(op); break;
- case 0:
- pushop(op);
- if (istackp!=1||opstackp)
- bail("Machine not in sane state on the end of expression, ints=%d,ops=%d!\n",istackp,opstackp);
- printf("%d\n",istack[0]);
- return;
- default: assert(0);
- }
-}
-
-int main(int argc,char **argv)
-{
-int argn;
- for (argn=1;argn<argc;argn++) {
- arg=argv[argn];
- process();
- }
- return(EXIT_SUCCESS);
-}