void popThenAdd(char ch){ char stackTop = topStack(); if(isalpha(stackTop) || isdigit(stackTop)){ pushForTime(')'); pushForTime(pop()); pushForTime(ch); char stackTop_2 = topStack(); if(isalpha(stackTop_2) || isdigit(stackTop_2)){ pushForTime(pop()); push('('); while(topForTime != NULL){ push(popForTime()); } }else{ foundObject(); } }else{ pushForTime(')'); while(top != NULL){ char popStack = pop(); if(popStack == ')'){ cnt1++; pushForTime(popStack); } else if(popStack == '('){ cnt2++; if(cnt1 == cnt2){ cnt1 = cnt2 = 0; pushForTime(popStack); pushForTime(ch); char popStack_2 = topStack(); if(isalpha(popStack_2) || isdigit(popStack_2)){ pushForTime(pop()); push('('); while(topForTime != NULL){ push(popForTime()); } break; }else{ foundObject(); break; } }else{ pushForTime(popStack); } }else{ pushForTime(popStack); } } } }
// ----------------------------------------------------------- Free evaluator object void freeEval( Eval ev ) { while (!isemptyStack( ev->Ators )) { freeOperator( topStack( ev->Ators ) ); popStack( ev->Ators ); } freeStack( ev->Ators ); while (!isemptyStack( ev->Ands )) { freeOperand( topStack( ev->Ands ) ); popStack( ev->Ands ); } freeStack( ev->Ands ); free( ev ); }
// ------------------------------------------------------------ Evaluate one operator. void dispatchEval( Eval ev ) { double result; Operand rightp = topStack( ev->Ands ); popStack( ev->Ands ); Operand leftp = topStack( ev->Ands ); popStack( ev->Ands ); double right = value( rightp ); freeOperand( rightp ); double left = value( leftp ); freeOperand( leftp ); Operator op = topStack( ev->Ators); popStack( ev->Ators ); ev->numbin--; printf( " Evaluating: %g%c%g\n", left, symbolOperator( op ), right ); switch ( symbolOperator( op ) ) { case '+': result = left + right; break; case '-': result = left - right; break; case '*': result = left * right; break; case '/': result = left / right; break; case '%': result = fmod(left, right); break; case '^': result = pow (left, right); break; default: result = HUGE_VAL; /* shouldn't occur */ } freeOperator( op ); Operand And = newOperand( result ); pushStack( ev->Ands, And ); }
void NEAR parse() { UCHAR stackTop, token, nextToken = 0; register unsigned n, i; firstToken = TRUE; /* global var */ pushStack(ACCEPT); /* init stack */ pushStack(START); currentLine = line; token = getToken(MAXBUF,START); /* get first token*/ while ((stackTop = topStack()) != ACCEPT) { if (ON(stackTop,ACTION_MASK)) doAction(popStack()); else if (ON(stackTop,TOKEN_MASK)) { if (stackTop != token) makeError(currentLine,SYNTAX+FATAL_ERR,buf); else { popStack(); #ifdef DEBUG_ALL printf ("DEBUG: parse 1: %d\n", line); #endif if (ON(topStack(),ACTION_MASK)) doAction(popStack()); #ifdef DEBUG_ALL printf ("DEBUG: parse 2: %d\n", line); #endif currentLine = line; if (nextToken) { /* if we already */ if (*buf == '\n') --currentLine; /* have a token, */ token = nextToken; /* use it . . . */ nextToken = 0; } else token = getToken(MAXBUF,topStack()); } } else { n = table[stackTop][token & LOW_NIBBLE]; #ifdef DEBUG_ALL printf ("DEBUG: parse 3: %x %d %x %x\n", n, stackTop, token & LOW_NIBBLE, token); #endif if (ON(n,ERROR_MASK)) { #ifdef DEBUG_ALL printf ("DEBUG: parse 4: %d %s\n", line, buf); #endif makeError(currentLine,n+FATAL_ERR,buf); } popStack(); if (ON(n,AMBIG_MASK)) { /* 2 possible prod*/ n &= LOW_NIBBLE; /* only use 4 bits*/ if (!nextToken) /* peek to decide */ nextToken = getToken(MAXBUF,stackTop); n += (useAlternate[stackTop][nextToken & LOW_NIBBLE]); } for (i = productions[n][0]; i; --i) /* put production */ pushStack(productions[n][i]); /* on stack */ } /* 1st elt in prod*/ } /* is its length */ popStack(); /* pop the ACCEPT off the stack */ }
// -------------------------------- Evaluate all higher precedence operators on stack. void forceEval( Eval ev, int rprec ) { while( sizeStack( ev->Ators ) > 0 && precedenceOperator( (const Operator) topStack( ev->Ators ) ) >= rprec ) { dispatchEval( ev ); } }
//------------------------------------------------ Read input and evaluate expression. double evaluateEval(Eval ev) { Intype next; // Classification of next input character. char inSymbol; // Read input operators into this. Operator inOp; // Operator object constructed from inSymbol. double inNumVal; // Read input operands into this. Operand And; // Operand value int numread; int n; for (;;) { next = classifyEval(ev); switch (next) { case number: n = sscanf(ev->instream, "%lg%n", &inNumVal, &numread); ev->instream += numread; if (n!=1 || sizeStack(ev->Ands) != ev->numbin) return expErrorEval(ev); And = newOperand(inNumVal); pushStack(ev->Ands, And); break; case op: if (sizeStack(ev->Ands) != ev->numbin+1) return expErrorEval(ev); inSymbol = *(ev->instream++); inOp = newOperator(inSymbol); forceEval(ev, precedenceOperator(inOp) ); pushStack(ev->Ators, inOp); ev->numbin++; break; case lpar: if (sizeStack(ev->Ands) != ev->numbin) return expErrorEval(ev); inSymbol = *(ev->instream++); inOp = newOperator(inSymbol); // put left paren on Ators stack pushStack(ev->Ators, inOp); break; case rpar: n = sscanf(ev->instream, " %c%n", &inSymbol, &numread); ev->instream += numread; if (sizeStack(ev->Ands) != ev->numbin+1) return expErrorEval(ev); forceEval(ev, 0); if (isemptyStack(ev->Ators)) expErrorEval(ev); // too many right parens Operator op = topStack(ev->Ators); // remove left paren operator from Ators stack freeOperator(op); popStack(ev->Ators); break; case end: if (sizeStack(ev->Ands) != ev->numbin+1) return expErrorEval(ev); forceEval(ev, 0); if (!isemptyStack(ev->Ators)) return expErrorEval(ev); And = topStack(ev->Ands); popStack(ev->Ands); double retval = value(And); freeOperand(And); return retval; break; case bad: default: return expErrorEval(ev); } } }