Annotation of 42BSD/ingres/source/monitor/expr.c, revision 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.