# 2.11BSD#431 - /usr/ingres/source/monitor/expr.c

##### Functions

    exp_op            X
    expr              X
    exprfind          X
    exprgch           X
    numberget         X
    opfind            X
    popnum            X
    popop             X
    pushnum           X
    pushop            X
    valof             X

##### Variables

    ExprError         X
    ExprNptr          X
    ExprNstack        X
    ExprOptr          X
    ExprOstack        X
    ExprPeek          X
    ExprPrec          X

##### Macros

    ADD               X
    AND               X
    DIVIDE            X
    END               X
    EQUALS            X
    GEQ               X
    GREATER           X
    LEQ               X
    LESS              X
    MOD               X
    MULTIPLY          X
    NEQ               X
    OR                X
    RIGHTP            X
    SEPERATOR         X
    STACKSZ           X
    SUBTRACT          X

       1: # include   "../ingres.h"
       2:
       3: /*
       4: **  EXPR -- evaluate expression
       5: **
       6: **	This module evaluates an expression in somewhat standard
       7: **	infix notation.  Several restrictions apply.  There are
       8: **	no variables, since this can be simulated with the macro
       9: **	processor.  No numeric overflow is checked.  There may be
      10: **	no spaces, tabs, or newlines in the expression.
      11: **
      12: **	The text of the expression is read from 'macgetch', so
      13: **	that must be initialized before calling this routine.
      14: **
      15: **	Operators accepted are + - * / < > >= <= = != % ( )
      16: **	& |.
      17: **	Operands may be signed integers.
      18: **	Standard precedence applies.
      19: **
      20: **	An expression can be viewed as a sequence of operands,
      21: **	and operators.  If the terminator is considered to be
      22: **	an operator, then the sequence must be composed
      23: ** 	of n matched pairs of operators and operands.  NOT and
      24: **	Negation are considered to be part of the operand and
      25: **	are treated as such.  Thus to evaluate an expression,
      26: **	n pairs are read until the terminator is found as the
      27: **	last operator.
      28: **
      29: **	Parameters:
      30: **		none
      31: **
      32: **	Returns:
      33: **		value of the expression.  Undetermined value
      34: **		on error.
      35: **
      36: **	Side Effects:
      37: **		Macro processing can occur.
      38: **
      39: **	Defines:
      40: **		expr -- the main entry point.
      41: **		valof -- the guts of the expression processor.
      42: **		exprfind -- finds and chews on operands.
      43: **		opfind -- finds and chews on operations.
      44: **		exp_op -- performs operations.
      45: **		numberget -- converts numbers.
      46: **		exprgch -- to get characters.
      47: **		pushop, popop, pushnum, popnum -- stack operations.
      48: **		ExprNstack, ExprNptr, ExprOstack, ExprOptr --
      49: **			stacks + associated data.
      50: **		ExprError -- an error flag.
      51: **		ExprPrec -- the precedence tables.
      52: **		ExprPeek -- the lookbehind character for exprgch.
      53: **
      54: **	Requires:
      55: **		macgetch -- to get the next character.
      56: **
      57: **	Required By:
      58: **		branch.c
      59: **
      60: **	Files:
      61: **		none
      62: **
      63: **	Trace Flags:
      64: **		none
      65: **
      66: **	History:
      67: **		8/15/79 (eric) (6.2/7) -- changed STACKSIZE to
      68: **			STACKSZ for v7 C compiler.
      69: **		2/27/79 -- written by John Woodfill, with some
      70: **			cleanup by Eric.
      71: */
      72:
      73:
      74:
      75:
      76:
      77:
      78: # define    STACKSZ     50
      79: # define    RIGHTP      21
      80: # define    END     22
      81: # define    SEPERATOR   0
      82: # define    OR      1
      83: # define    AND     2
      84: # define    EQUALS      3
      85: # define    NEQ     4
      86: # define    LESS        5
      87: # define    LEQ     6
      88: # define    GREATER     7
      89: # define    GEQ     8
      90: # define    ADD     9
      91: # define    SUBTRACT    10
      92: # define    MULTIPLY    11
      93: # define    DIVIDE      12
      94: # define    MOD     13
      95:
      96:
      97: int     ExprPrec[] =            /* Precedence table */
      98: {
      99:     0,  /* filler */
     100:     1,  /* 1 -- OR */
     101:     2,  /* 2 -- AND */
     102:     3,  /* 3 -- EQUALS */
     103:     3,  /* 4 -- NEQ */
     104:     4,  /* 5 -- LESS */
     105:     4,  /* 6 -- LEQ */
     106:     4,  /* 7 -- GREATER */
     107:     4,  /* 8 -- GEQ */
     108:     5,  /* 9 -- ADD */
     109:     5,  /* 10 -- SUBTRACT */
     110:     6,  /* 11 -- MULTIPLY */
     111:     6,  /* 12 -- DIVIDE */
     112:     6   /* 13 -- MOD */
     113: };
     114:
     115:
     116: int ExprNstack[STACKSZ];
     117: int *ExprNptr;
     118: int ExprOstack[STACKSZ];
     119: int *ExprOptr;
     120: int ExprError;
     121: char    ExprPeek;
     122:
     123:
     124:
     125:
     126:
     127:
     128:
     129:
     130:
     131:
     132:
     133: expr()
     134: {
     135:     ExprNptr = ExprNstack;
     136:     ExprOptr = ExprOstack;
     137:     ExprError = FALSE;
     138:     ExprPeek = -1;
     139:     return(valof(END));
     140: }
     141: /*
     142: **  VALOF -- compute value of expression
     143: **
     144: **	This is the real expression processor.  It handles sequencing
     145: **	and precedence.
     146: **
     147: **	Parameters:
     148: **		terminator -- the symbol which should terminate
     149: **			the expression.
     150: **
     151: **	Returns:
     152: **		The value of the expression.
     153: **
     154: **	Side Effects:
     155: **		Gobbles input.
     156: **
     157: **	Requires:
     158: **		exprfind -- to read operands.
     159: **		opfind -- to read operators.
     160: **		exp_op -- to perform operations.
     161: **
     162: **	Called By:
     163: **		expr
     164: **
     165: **	Diagnostics:
     166: **		Extra Parenthesis found: assumed typo
     167: **			An unmatched right parenthesis was read.
     168: **			It was thrown away.
     169: **		Insufficient parenthesis found: assumed zero.
     170: **			An unmatched left parenthesis was left
     171: **			in the operator stack at the end of the
     172: **			expression.  The value zero was taken
     173: **			for the expression.
     174: **
     175: **	Syserrs:
     176: **		none
     177: */
     178:
     179: valof(terminator)
     180: int terminator;
     181: {
     182:     register int    number;
     183:     register int    operator;
     184:
     185:     pushop(SEPERATOR);      /* initialize the stack */
     186:
     187:     for(;;)
     188:     {
     189:         number = exprfind();
     190:         if (ExprError)
     191:             return(0);
     192:         operator = opfind();
     193:         if (ExprError)
     194:             return(0);
     195:
     196:         if (operator == RIGHTP || operator == END)
     197:             break;
     198:
     199:         /* Do all previous operations with a higher precedence */
     200:         while (ExprPrec[operator] <= ExprPrec[ExprOptr[-1]])
     201:             number = exp_op(popop(), popnum(), number);
     202:         pushop(operator);
     203:         pushnum(number);
     204:     }
     205:     if (operator != terminator)     /* ExprError in operators */
     206:         if (operator == RIGHTP)
     207:             printf("Extra parenthesis found: assumed typo.\n");
     208:         else
     209:         {
     210:             ExprError = TRUE;
     211:             printf("Insufficient parenthesis found: Assumed zero.\n");
     212:             return(0);
     213:         }
     214:     /* Empty stack for this call of valof */
     215:     while ((operator = popop()) != SEPERATOR)
     216:         number = exp_op(operator, popnum(), number);
     217:
     218:     return(number);
     219: }
     220: /*
     221: **  EXPRFIND -- find and chomp operand
     222: **
     223: **	This routine reads the next operand.  It generally just
     224: **	reads numbers, except it also knows about unary operators
     225: **	! and - (where it calls itself recursively), and paren-
     226: **	theses (where it calls valof recursively).
     227: **
     228: **	Parameters:
     229: **		none
     230: **
     231: **	Returns:
     232: **		value of operand.
     233: **
     234: **	Side Effects:
     235: **		Gobbles input.
     236: **
     237: **	Requires:
     238: **		numberget -- to read numbers.
     239: **		exprgch.
     240: **
     241: **	Called By:
     242: **		valof
     243: **		exprfind (recursively)
     244: **
     245: **	Trace Flags:
     246: **		none
     247: **
     248: **	Diagnostics:
     249: **		Expression expected: end of expression found.
     250: **			Nothing was found.  Zero is returned.
     251: **		Expression expected: %c found; assumed zero.
     252: **			A syntax error -- nothing was found
     253: **			which was acceptable.
     254: */
     255:
     256:
     257:
     258: exprfind()
     259: {
     260:     register int    result;
     261:     register int    c;
     262:
     263:     c = exprgch();
     264:
     265:     switch(c)
     266:     {
     267:
     268:       case '0':
     269:       case '1':
     270:       case '2':
     271:       case '3':
     272:       case '4':
     273:       case '5':
     274:       case '6':
     275:       case '7':
     276:       case '8':
     277:       case '9':
     278:         return(numberget(c));
     279:
     280:       case '!':
     281:         result = exprfind();
     282:         return(ExprError ? 0 : (result <= 0));
     283:
     284:       case '-':
     285:         result = exprfind();
     286:         return(ExprError ? 0 : -result);
     287:
     288:       case '(':
     289:         return(valof(RIGHTP));
     290:
     291:       case ' ':
     292:       case '\n':
     293:       case '/t':
     294:       case '\0':
     295:         printf("Expression expected: end of expression found.\n");
     296:         ExprError = TRUE;
     297:         return(0);
     298:
     299:       default:
     300:         printf("Expression expected; '%c' found: Assumed zero.\n", c);
     301:         ExprError = TRUE;
     302:         return(0);
     303:     }
     304: }
     305: /*
     306: **  OPFIND -- find and translate operator
     307: **
     308: **	This reads the next operator from the input stream and
     309: **	returns the internal code for it.
     310: **
     311: **	Parameters:
     312: **		none
     313: **
     314: **	Returns:
     315: **		The code for the next operator.
     316: **		Zero on error.
     317: **
     318: **	Side Effects:
     319: **		Gobbles input.
     320: **
     321: **	Requires:
     322: **		exprgch.
     323: **
     324: **	Called By:
     325: **		valof
     326: **
     327: **	Trace Flags:
     328: **		none
     329: **
     330: **	Diagnostics:
     331: **		Operator expected: '%c' found.
     332: **			Gibberish in input.
     333: */
     334:
     335: opfind()
     336: {
     337:     register int    c;
     338:
     339:     c = exprgch();
     340:
     341:     switch(c)
     342:     {
     343:
     344:       case '/':
     345:         return(DIVIDE);
     346:
     347:       case '=':
     348:         return(EQUALS);
     349:
     350:       case  '&':
     351:         return(AND);
     352:
     353:       case '|':
     354:         return(OR);
     355:
     356:       case '+':
     357:         return(ADD);
     358:
     359:       case '-':
     360:         return(SUBTRACT);
     361:
     362:       case '*':
     363:         return(MULTIPLY);
     364:
     365:       case '<':
     366:         c = exprgch();
     367:         if (c == '=')
     368:         {
     369:             return(LEQ);
     370:         }
     371:         ExprPeek = c;
     372:         return(LESS);
     373:
     374:       case '>':
     375:         c = exprgch();
     376:         if (c == '=')
     377:         {
     378:             return(GEQ);
     379:         }
     380:         ExprPeek = c;
     381:         return(GREATER);
     382:
     383:       case '%':
     384:         return(MOD);
     385:
     386:       case '!':
     387:         c = exprgch();
     388:         if (c == '=')
     389:         {
     390:             return(NEQ);
     391:         }
     392:         else
     393:         {
     394:             printf("Operator expected: '!%c' found.\n", c);
     395:             ExprError = TRUE;
     396:             return(0);
     397:         }
     398:
     399:       case ')':
     400:         return(RIGHTP);
     401:
     402:       case ' ':
     403:       case '\t':
     404:       case '\n':
     405:       case '\0':
     406:         return(END);
     407:
     408:       default:
     409:         printf("Operator expected: '%c' found.\n", c);
     410:         ExprError = TRUE;
     411:         return(0);
     412:
     413:     }
     414: }
     415: /*
     416: **  EXP_OP -- perform operation
     417: **
     418: **	Performs an operation between two values.
     419: **
     420: **	Parameters:
     421: **		op -- the operation to perform.
     422: **		lv -- the left operand.
     423: **		rv -- the right operand.
     424: **
     425: **	Returns:
     426: **		The value of the operation.
     427: **
     428: **	Side Effects:
     429: **		none
     430: **
     431: **	Requires:
     432: **		none
     433: **
     434: **	Called By:
     435: **		valof.
     436: **
     437: **	Trace Flags:
     438: **		none
     439: **
     440: **	Diagnostics:
     441: **		none
     442: */
     443:
     444: exp_op(op, lv, rv)
     445: int op;
     446: int lv;
     447: int rv;
     448: {
     449:     switch(op)
     450:     {
     451:
     452:       case OR:
     453:         return((lv > 0) || (rv > 0));
     454:
     455:       case AND:
     456:         return((lv > 0) && (rv > 0));
     457:
     458:       case EQUALS:
     459:         return(lv == rv);
     460:
     461:       case NEQ:
     462:         return(lv != rv);
     463:
     464:       case LESS:
     465:         return(lv < rv);
     466:
     467:       case LEQ:
     468:         return(lv <= rv);
     469:
     470:       case GREATER:
     471:         return(lv > rv);
     472:
     473:       case GEQ:
     474:         return(lv >= rv);
     475:
     476:       case ADD:
     477:         return(lv + rv);
     478:
     479:       case SUBTRACT:
     480:         return(lv - rv);
     481:
     482:       case MULTIPLY:
     483:         return(lv * rv);
     484:
     485:       case DIVIDE:
     486:         if (rv == 0)
     487:         {
     488:             printf("Divide by zero: zero assumed.\n");
     489:             return(0);
     490:         }
     491:         else
     492:             return(lv / rv);
     493:
     494:       case MOD:
     495:         return(lv % rv);
     496:
     497:       default:
     498:         syserr("exp_op: bad op %d", op);
     499:
     500:     }
     501: }
     502: /*
     503: **  NUMBERGET -- read and convert a number
     504: **
     505: **	Reads and converts a signed integer.
     506: **
     507: **	Parameters:
     508: **		none
     509: **
     510: **	Returns:
     511: **		The next number in the input stream.
     512: **
     513: **	Side Effects:
     514: **		Gobbles input.
     515: **
     516: **	Requires:
     517: **		exprgch.
     518: **
     519: **	Called By:
     520: **		exprfind.
     521: */
     522:
     523: numberget(cx)
     524: char    cx;
     525: {
     526:     register int    result;
     527:     register int    c;
     528:
     529:     c = cx;
     530:
     531:     result = 0;
     532:     do
     533:     {
     534:         result = result * 10 + c - '0';
     535:         c = exprgch();
     536:     } while (c >= '0' && c <= '9');
     537:     ExprPeek = c;
     538:     return(result);
     539: }
     540: /*
     541: **  EXPRGCH -- expression character get
     542: **
     543: **	Gets the next character from the expression input.  Takes
     544: **	a character out of ExprPeek first.  Also maps spaces, tabs,
     545: **	and newlines into zero bytes.
     546: **
     547: **	Parameters:
     548: **		none
     549: **
     550: **	Returns:
     551: **		Next character.
     552: **
     553: **	Side Effects:
     554: **		Gobbles input.
     555: **		Clears ExprPeek if set.
     556: **
     557: **	Requires:
     558: **		ExprPeek -- the peek character.
     559: **		macgetch -- to get the next character if ExprPeek
     560: **			is not set.
     561: */
     562:
     563: exprgch()
     564: {
     565:     register int    c;
     566:
     567:     c = ExprPeek;
     568:     if (c < 0)
     569:         c = macgetch();
     570:     ExprPeek = -1;
     571:     if (c == ' ' || c == '\n' || c == '\t')
     572:         c = 0;
     573:     return (c);
     574: }
     575: /*
     576: **  Stack operations.
     577: */
     578:
     579:
     580: /* Popop returns the top of the operator stack and decrements this stack. */
     581: popop()
     582: {
     583:     if (ExprOptr <= ExprOstack)
     584:         syserr("popop: underflow");
     585:     return(*--ExprOptr);
     586: }
     587:
     588:
     589:
     590: /* Pushop increments the stack pointer and pushes op on the stack. */
     591: pushop(op)
     592: int op;
     593: {
     594:     *ExprOptr++ = op;
     595: }
     596:
     597:
     598:
     599: /* Popnum returns the top of the number stack and decrements the stack pointer. */
     600: popnum()
     601: {
     602:     if (ExprNptr <= ExprNstack)
     603:         syserr("popnum: underflow");
     604:     return(*--ExprNptr);
     605: }
     606:
     607:
     608:
     609:
     610: /* Pushnum increments the stack pointer and pushes num onto the stack */
     611: pushnum(num)
     612: int     num;
     613: {
     614:     *ExprNptr++ = num;
     615: }

#### Defined functions

exp_op defined in line 444; used 2 times

- in line 201, 216

expr defined in line 133; used 1 times

- in /usr/ingres/source/monitor/branch.c line 39

exprfind defined in line 258; used 3 times

- in line 189, 281-285(2)

exprgch defined in line 563; used 6 times

- in line 263, 339, 366, 375, 387, 535

numberget defined in line 523; used 1 times

- in line 278

opfind defined in line 335; used 1 times

- in line 192

popnum defined in line 600; used 2 times

- in line 201, 216

popop defined in line 581; used 2 times

- in line 201, 215

pushnum defined in line 611; used 1 times

- in line 203

pushop defined in line 591; used 2 times

- in line 185, 202

valof defined in line 179; used 2 times

- in line 139, 289

#### Defined variables

ExprError defined in line 120; used 10 times

- in line 137, 190-193(2), 210, 282-286(2), 296-301(2), 395, 410

ExprNptr defined in line 117; used 4 times

- in line 135, 602-604(2), 614

ExprNstack defined in line 116; used 2 times

- in line 135, 602

ExprOptr defined in line 119; used 5 times

- in line 136, 200, 583-585(2), 594

ExprOstack defined in line 118; used 2 times

- in line 136, 583

ExprPeek defined in line 121; used 6 times

- in line 138, 371, 380, 537, 567-570(2)

ExprPrec defined in line 97; used 2 times

- in line 200(2)

#### Defined macros

ADD defined in line 90; used 1 times

- in line 357

AND defined in line 83; used 1 times

- in line 351

DIVIDE defined in line 93; used 1 times

- in line 345

END defined in line 80; used 3 times

- in line 139, 196, 406

EQUALS defined in line 84; used 1 times

- in line 348

GEQ defined in line 89; used 1 times

- in line 378

GREATER defined in line 88; used 1 times

- in line 381

LEQ defined in line 87; used 1 times

- in line 369

LESS defined in line 86; used 1 times

- in line 372

MOD defined in line 94; used 1 times

- in line 384

MULTIPLY defined in line 92; used 1 times

- in line 363

NEQ defined in line 85; used 1 times

- in line 390

OR defined in line 82; used 1 times

- in line 354

RIGHTP defined in line 79; used 4 times

- in line 196, 206, 289, 400

SEPERATOR defined in line 81; used 2 times

- in line 185, 215

STACKSZ defined in line 78; used 2 times

- in line 116-118(2)

SUBTRACT defined in line 91; used 1 times

- in line 360

Last modified: 1995-02-04 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1451 |