⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expr.c

📁 操作系统源代码
💻 C
字号:
/* *      expression evaluator: performs a standard recursive *      descent parse to evaluate any expression permissible *      within the following grammar: * *      expr    :       query EOS *      query   :       lor *              |       lor "?" query ":" query *      lor     :       land { "||" land } *      land    :       bor { "&&" bor } *      bor     :       bxor { "|" bxor } *      bxor    :       band { "^" band } *      band    :       eql { "&" eql } *      eql     :       relat { eqrel relat } *      relat   :       shift { rel shift } *      shift   :       primary { shop primary } *      primary :       term { addop term } *      term    :       unary { mulop unary } *      unary   :       factor *              |       unop unary *      factor  :       constant *              |       "(" query ")" *      constant:       num *              |       "'" CHAR "'" *      num     :       DIGIT *              |       DIGIT num *      shop    :       "<<" *              |       ">>" *      eqlrel  :       "=" *              |       "==" *              |       "!=" *      rel     :       "<" *              |       ">" *              |       "<=" *              |       ">=" * * *      This expression evaluator is lifted from a public-domain *      C Pre-Processor included with the DECUS C Compiler distribution. *      It is hacked somewhat to be suitable for m4. * *      Originally by:  Mike Lutz *                      Bob Harper */ #include "mdef.h"#define TRUE    1#define FALSE   0#define EOS     (char) 0#define EQL     0#define NEQ     1#define LSS     2#define LEQ     3#define GTR     4#define GEQ     5#define OCTAL   8#define DECIMAL 10 static char *nxtch;     /* Parser scan pointer */ /* * For longjmp */#include <setjmp.h>static jmp_buf  expjump; /* * macros: * *      ungetch - Put back the last character examined. *      getch   - return the next character from expr string. */#define ungetch()       nxtch--#define getch()         *nxtch++ int expr(expbuf)char *expbuf;{        register int rval;         nxtch = expbuf;        if (setjmp(expjump) != 0)                return (FALSE);        rval = query();        if (skipws() == EOS)                return(rval);        experr("Ill-formed expression");	/* NOTREACHED */	return(0);} /* * query : lor | lor '?' query ':' query * */int query(){        register int bool, true_val, false_val;         bool = lor();        if (skipws() != '?') {                ungetch();                return(bool);        }         true_val = query();        if (skipws() != ':')                experr("Bad query");         false_val = query();        return(bool ? true_val : false_val);} /* * lor : land { '||' land } * */int lor(){        register int c, vl, vr;         vl = land();        while ((c = skipws()) == '|' && getch() == '|') {                vr = land();                vl = vl || vr;        }         if (c == '|')                ungetch();        ungetch();        return(vl);} /* * land : bor { '&&' bor } * */int land(){        register int c, vl, vr;         vl = bor();        while ((c = skipws()) == '&' && getch() == '&') {                vr = bor();                vl = vl && vr;        }         if (c == '&')                ungetch();        ungetch();        return(vl);} /* * bor : bxor { '|' bxor } * */int bor(){        register int vl, vr, c;         vl = bxor();        while ((c = skipws()) == '|' && getch() != '|') {                ungetch();                vr = bxor();                vl |= vr;        }         if (c == '|')                ungetch();        ungetch();        return(vl);} /* * bxor : band { '^' band } * */int bxor(){        register int vl, vr;         vl = band();        while (skipws() == '^') {                vr = band();                vl ^= vr;        }         ungetch();        return(vl);} /* * band : eql { '&' eql } * */int band(){        register int vl, vr, c;         vl = eql();        while ((c = skipws()) == '&' && getch() != '&') {                ungetch();                vr = eql();                vl &= vr;        }         if (c == '&')                ungetch();        ungetch();        return(vl);} /* * eql : relat { eqrel relat } * */int eql(){        register int vl, vr, rel;         vl = relat();        while ((rel = geteql()) != -1) {                vr = relat();                 switch (rel) {                 case EQL:                        vl = (vl == vr);                        break;                case NEQ:                        vl = (vl != vr);                        break;                }        }        return(vl);} /* * relat : shift { rel shift } * */int relat(){        register int vl, vr, rel;         vl = shift();        while ((rel = getrel()) != -1) {                 vr = shift();                switch (rel) {                 case LEQ:                        vl = (vl <= vr);                        break;                case LSS:                        vl = (vl < vr);                        break;                case GTR:                        vl = (vl > vr);                        break;                case GEQ:                        vl = (vl >= vr);                        break;                }        }        return(vl);} /* * shift : primary { shop primary } * */int shift(){        register int vl, vr, c;         vl = primary();        while (((c = skipws()) == '<' || c == '>') && c == getch()) {                vr = primary();                 if (c == '<')                        vl <<= vr;                else                        vl >>= vr;        }         if (c == '<' || c == '>')                ungetch();        ungetch();        return(vl);} /* * primary : term { addop term } * */int primary(){        register int c, vl, vr;         vl = term();        while ((c = skipws()) == '+' || c == '-') {                vr = term();                if (c == '+')                        vl += vr;                else                        vl -= vr;        }         ungetch();        return(vl);} /* * <term> := <unary> { <mulop> <unary> } * */int term(){        register int c, vl, vr;         vl = unary();        while ((c = skipws()) == '*' || c == '/' || c == '%') {                vr = unary();                 switch (c) {                case '*':                        vl *= vr;                        break;                case '/':                        vl /= vr;                        break;                case '%':                        vl %= vr;                        break;                }        }        ungetch();        return(vl);} /* * unary : factor | unop unary * */int unary(){        register int val, c;         if ((c = skipws()) == '!' || c == '~' || c == '-') {                val = unary();                 switch (c) {                case '!':                        return(! val);                case '~':                        return(~ val);                case '-':                        return(- val);                }        }         ungetch();        return(factor());} /* * factor : constant | '(' query ')' * */int factor(){        register int val;         if (skipws() == '(') {                val = query();                if (skipws() != ')')                        experr("Bad factor");                return(val);        }         ungetch();        return(constant());} /* * constant: num | 'char' * */int constant(){        /*         * Note: constant() handles multi-byte constants         */         register int    i;        register int    value;        register char   c;        int             v[sizeof (int)];         if (skipws() != '\'') {                ungetch();                return(num());        }        for (i = 0; i < sizeof(int); i++) {                if ((c = getch()) == '\'') {                        ungetch();                        break;                }                if (c == '\\') {                        switch (c = getch()) {                        case '0':                        case '1':                        case '2':                        case '3':                        case '4':                        case '5':                        case '6':                        case '7':                                ungetch();                                c = num();                                break;                        case 'n':                                c = 012;                                break;                        case 'r':                                c = 015;                                break;                        case 't':                                c = 011;                                break;                        case 'b':                                c = 010;                                break;                        case 'f':                                c = 014;                                break;                        }                }                v[i] = c;        }        if (i == 0 || getch() != '\'')                experr("Illegal character constant");        for (value = 0; --i >= 0;) {                value <<= 8;                value += v[i];        }        return(value);} /* * num : digit | num digit * */int num(){        register int rval, c, base;        int ndig;         base = ((c = skipws()) == '0') ? OCTAL : DECIMAL;        rval = 0;        ndig = 0;        while (c >= '0' && c <= (base == OCTAL ? '7' : '9')) {                rval *= base;                rval += (c - '0');                c = getch();                ndig++;        }        ungetch();        if (ndig)                return(rval);        experr("Bad constant");	/* NOTREACHED */	return(0);} /* * eqlrel : '=' | '==' | '!=' * */int geteql(){        register int c1, c2;         c1 = skipws();        c2 = getch();         switch (c1) {         case '=':                if (c2 != '=')                        ungetch();                return(EQL);         case '!':                if (c2 == '=')                        return(NEQ);                ungetch();                ungetch();                return(-1);         default:                ungetch();                ungetch();                return(-1);        }} /* * rel : '<' | '>' | '<=' | '>=' * */int getrel(){        register int c1, c2;         c1 = skipws();        c2 = getch();         switch (c1) {         case '<':                if (c2 == '=')                        return(LEQ);                ungetch();                return(LSS);         case '>':                if (c2 == '=')                        return(GEQ);                ungetch();                return(GTR);         default:                ungetch();                ungetch();                return(-1);        }} /* * Skip over any white space and return terminating char. */int skipws(){        register char c;         while ((c = getch()) <= ' ' && c > EOS)                ;        return(c);} /* * Error handler - resets environment to eval(), prints an error, * and returns FALSE. */int experr(msg)char *msg;{        printf("mp: %s\n",msg);        longjmp(expjump, -1);          /* Force eval() to return FALSE */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -