Annotation of 42BSD/ingres/source/monitor/expr.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.