[hackeroid] hscool ONLINE: Eval.c Sutra
    
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / / ANSI Eval.c hscool sutra / / / / Expression calculator / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <limits.h> #include <math.h> #define IF(c) case c: GetToken(); typedef const char *const CSTR; static const char *sExpression; static int iChar; /* get char from command line or input stream */ #define GetChar() ((void)(iChar=sExpression? *sExpression++ : getchar())) typedef float T; static struct { enum { ID_ENDLINE=CHAR_MAX+1,ID_CONSTANT } id; T v; } token; static void Abend(CSTR s) /* abnormal end with error message */ { printf("%s.\n",s); exit(EXIT_FAILURE); } static T Expression(void); /* forward reference for recurse in Factor() */ static void GetToken(void) /* lexical parser */ { while(iChar==' ' || iChar=='\t') GetChar(); if(isdigit(token.id=iChar)) { int iTailCnt=0,iTailFlg=0; token.v=0; do { token.v=token.v*10+iChar-'0'; GetChar(); if(iTailFlg) iTailCnt++; else if(iChar=='.') GetChar(), iTailFlg=1; } while(isdigit(iChar)); token.id=ID_CONSTANT; token.v/=pow(10,iTailCnt); } else if(iChar=='\n' || iChar=='\0') token.id=ID_ENDLINE; else GetChar(); } static T Factor(void) /* proceed constant, negation or parentheses */ /* <FACTOR> ::= CONSTANT | `-' <FACTOR> | `(' <EXPRESSION> `)' */ { T v; switch(token.id) { default: Abend("Syntax error"); case ID_CONSTANT: v=token.v; break; IF('-') return -Factor(); IF('(') v=Expression(); if(token.id!=')') Abend("Missing `)'"); } GetToken(); return v; } static T Term(void) /* multiply or divide */ /* <TERM> ::= <FACTOR> { ( `*' | `^' | `/' ) <FACTOR> } */ { T v=Factor(),vDivisor; for(;;) switch(token.id) { default: return v; IF('*') v*=Factor(); continue; IF('^') v=pow(v,Factor()); continue; IF('/') if((vDivisor=Factor())==0) Abend("Division by zero"); v/=vDivisor; } } static T Expression(void) /* add or subtract */ /* <EXPRESSION> ::= <TERM> { ( `+' | `-' ) <TERM> } */ { T v=Term(); for(;;) switch(token.id) { default: return v; IF('+') v+=Term(); continue; IF('-') v-=Term(); } } T Eval(CSTR s) /* function that calculates */ { static T v; sExpression=s; GetChar(); GetToken(); v=Expression(); if(token.id!=ID_ENDLINE) Abend("Syntax error"); return v; } int main(const int iArgCount,CSTR psArgValues[]) /* program entry point */ { static float f; printf("\rEval. Evaluates an expression. Eval -? for help.\n"); switch(iArgCount) { case 2: if(strcmp(psArgValues[1],"-?")) { printf(" Expression: %s\n",psArgValues[1]); break; } default: printf(" Operators: + - * / ^ The last one is power. " "Parentheses are allowed.\n" "Example: Eval \"7+0.9^5*200/(39-45)\"\n"); return 0; case 1: printf(" Expression: "); } printf("Result: %.3f\n",f=Eval(psArgValues[1])); return (int)f; }


E-mail: hscool@netclub.ru