Annotation of researchv9/cmd/expr/expr.y, revision 1.1.1.1

1.1       root        1: /* Yacc productions for "expr" command: */
                      2: 
                      3: %token OR AND ADD SUBT MULT DIV REM EQ GT GEQ LT LEQ NEQ
                      4: %token A_STRING SUBSTR LENGTH INDEX NOARG MATCH
                      5: 
                      6: /* operators listed below in increasing precedence: */
                      7: %left OR
                      8: %left AND
                      9: %left EQ LT GT GEQ LEQ NEQ
                     10: %left ADD SUBT
                     11: %left MULT DIV REM
                     12: %left MCH
                     13: %left MATCH
                     14: %left SUBSTR
                     15: %left LENGTH INDEX
                     16: %%
                     17: 
                     18: /* a single `expression' is evaluated and printed: */
                     19: 
                     20: expression:    expr NOARG = {
                     21:                        prt(1, $1);
                     22:                        exit((!strcmp($1,"0")||!strcmp($1,"\0"))? 1: 0);
                     23:                        }
                     24:        ;
                     25: 
                     26: 
                     27: expr:  '(' expr ')' = { $$ = $2; }
                     28:        | expr OR expr   = { $$ = conj(OR, $1, $3); }
                     29:        | expr AND expr   = { $$ = conj(AND, $1, $3); }
                     30:        | expr EQ expr   = { $$ = rel(EQ, $1, $3); }
                     31:        | expr GT expr   = { $$ = rel(GT, $1, $3); }
                     32:        | expr GEQ expr   = { $$ = rel(GEQ, $1, $3); }
                     33:        | expr LT expr   = { $$ = rel(LT, $1, $3); }
                     34:        | expr LEQ expr   = { $$ = rel(LEQ, $1, $3); }
                     35:        | expr NEQ expr   = { $$ = rel(NEQ, $1, $3); }
                     36:        | expr ADD expr   = { $$ = arith(ADD, $1, $3); }
                     37:        | expr SUBT expr   = { $$ = arith(SUBT, $1, $3); }
                     38:        | expr MULT expr   = { $$ = arith(MULT, $1, $3); }
                     39:        | expr DIV expr   = { $$ = arith(DIV, $1, $3); }
                     40:        | expr REM expr   = { $$ = arith(REM, $1, $3); }
                     41:        | expr MCH expr  = { $$ = match($1, $3); }
                     42:        | MATCH expr expr = { $$ = match($2, $3); }
                     43:        | SUBSTR expr expr expr = { $$ = substr($2, $3, $4); }
                     44:        | LENGTH expr       = { $$ = length($2); }
                     45:        | INDEX expr expr = { $$ = index($2, $3); }
                     46:        | A_STRING
                     47:        ;
                     48: %%
                     49: /*     expression command */
                     50: #include <stdio.h>
                     51: /* get rid of yacc debug printf's */
                     52: #define printf
                     53: #define ESIZE  512
                     54: #define error(c)       errxx(c)
                     55: #define EQL(x,y) !strcmp(x,y)
                     56: long atol();
                     57: char *ltoa();
                     58: char   **Av;
                     59: int    Ac;
                     60: int    Argi;
                     61: 
                     62: char Mstring[1][128];
                     63: char *malloc();
                     64: extern int nbra;
                     65: 
                     66: main(argc, argv) char **argv; {
                     67:        Ac = argc;
                     68:        Argi = 1;
                     69:        Av = argv;
                     70:        yyparse();
                     71: }
                     72: 
                     73: char *operator[] = { "|", "&", "+", "-", "*", "/", "%", ":",
                     74:        "=", "==", "<", "<=", ">", ">=", "!=",
                     75:        "match", "substr", "length", "index", "\0" };
                     76: int op[] = { OR, AND, ADD,  SUBT, MULT, DIV, REM, MCH,
                     77:        EQ, EQ, LT, LEQ, GT, GEQ, NEQ,
                     78:        MATCH, SUBSTR, LENGTH, INDEX };
                     79: yylex() {
                     80:        register char *p;
                     81:        register i;
                     82: 
                     83:        if(Argi >= Ac) return NOARG;
                     84: 
                     85:        p = Av[Argi++];
                     86: 
                     87:        if(*p == '(' || *p == ')')
                     88:                return (int)*p;
                     89:        for(i = 0; *operator[i]; ++i)
                     90:                if(EQL(operator[i], p))
                     91:                        return op[i];
                     92: 
                     93:        yylval = p;
                     94:        return A_STRING;
                     95: }
                     96: 
                     97: char *rel(op, r1, r2) register char *r1, *r2; {
                     98:        register i;
                     99: 
                    100:        if(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$"))
                    101:                i = atol(r1) - atol(r2);
                    102:        else
                    103:                i = strcmp(r1, r2);
                    104:        switch(op) {
                    105:        case EQ: i = i==0; break;
                    106:        case GT: i = i>0; break;
                    107:        case GEQ: i = i>=0; break;
                    108:        case LT: i = i<0; break;
                    109:        case LEQ: i = i<=0; break;
                    110:        case NEQ: i = i!=0; break;
                    111:        }
                    112:        return i? "1": "0";
                    113: }
                    114: 
                    115: char *arith(op, r1, r2) char *r1, *r2; {
                    116:        long i1, i2;
                    117:        register char *rv;
                    118: 
                    119:        if(!(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$")))
                    120:                yyerror("non-numeric argument");
                    121:        i1 = atol(r1);
                    122:        i2 = atol(r2);
                    123: 
                    124:        switch(op) {
                    125:        case ADD: i1 = i1 + i2; break;
                    126:        case SUBT: i1 = i1 - i2; break;
                    127:        case MULT: i1 = i1 * i2; break;
                    128:        case DIV: i1 = i1 / i2; break;
                    129:        case REM: i1 = i1 % i2; break;
                    130:        }
                    131:        rv = malloc(16);
                    132:        strcpy(rv, ltoa(i1));
                    133:        return rv;
                    134: }
                    135: char *conj(op, r1, r2) char *r1, *r2; {
                    136:        register char *rv;
                    137: 
                    138:        switch(op) {
                    139: 
                    140:        case OR:
                    141:                if(EQL(r1, "0")
                    142:                || EQL(r1, ""))
                    143:                        if(EQL(r2, "0")
                    144:                        || EQL(r2, ""))
                    145:                                rv = "0";
                    146:                        else
                    147:                                rv = r2;
                    148:                else
                    149:                        rv = r1;
                    150:                break;
                    151:        case AND:
                    152:                if(EQL(r1, "0")
                    153:                || EQL(r1, ""))
                    154:                        rv = "0";
                    155:                else if(EQL(r2, "0")
                    156:                || EQL(r2, ""))
                    157:                        rv = "0";
                    158:                else
                    159:                        rv = r1;
                    160:                break;
                    161:        }
                    162:        return rv;
                    163: }
                    164: 
                    165: char *substr(v, s, w) char *v, *s, *w; {
                    166: register si, wi;
                    167: register char *res;
                    168: 
                    169:        si = atol(s);
                    170:        wi = atol(w);
                    171:        while(--si) if(*v) ++v;
                    172: 
                    173:        res = v;
                    174: 
                    175:        while(wi--) if(*v) ++v;
                    176: 
                    177:        *v = '\0';
                    178:        return res;
                    179: }
                    180: 
                    181: char *length(s) register char *s; {
                    182:        register i = 0;
                    183:        register char *rv;
                    184: 
                    185:        while(*s++) ++i;
                    186: 
                    187:        rv = malloc(8);
                    188:        strcpy(rv, ltoa((long)i));
                    189:        return rv;
                    190: }
                    191: 
                    192: char *index(s, t) char *s, *t; {
                    193:        register i, j;
                    194:        register char *rv;
                    195: 
                    196:        for(i = 0; s[i] ; ++i)
                    197:                for(j = 0; t[j] ; ++j)
                    198:                        if(s[i]==t[j]) {
                    199:                                strcpy(rv=malloc(8), ltoa((long)++i));
                    200:                                return rv;
                    201:                        }
                    202:        return "0";
                    203: }
                    204: 
                    205: char *match(s, p)
                    206: {
                    207:        register char *rv;
                    208: 
                    209:        strcpy(rv=malloc(8), ltoa((long)ematch(s, p)));
                    210:        if(nbra) {
                    211:                rv = malloc(strlen(Mstring[0])+1);
                    212:                strcpy(rv, Mstring[0]);
                    213:        }
                    214:        return rv;
                    215: }
                    216: 
                    217: #define INIT   register char *sp = instring;
                    218: #define GETC()         (*sp++)
                    219: #define PEEKC()                (*sp)
                    220: #define UNGETC(c)      (--sp)
                    221: #define RETURN(c)      return
                    222: #define ERROR(c)       errxx(c)
                    223: 
                    224: 
                    225: ematch(s, p)
                    226: char *s;
                    227: register char *p;
                    228: {
                    229:        static char expbuf[ESIZE];
                    230:        char *compile();
                    231:        register num;
                    232:        extern char *braslist[], *braelist[], *loc2;
                    233: 
                    234:        compile(p, expbuf, &expbuf[ESIZE], 0);
                    235:        if(nbra > 1)
                    236:                yyerror("Too many '\\('s");
                    237:        if(advance(s, expbuf)) {
                    238:                if(nbra == 1) {
                    239:                        p = braslist[0];
                    240:                        num = braelist[0] - p;
                    241:                        strncpy(Mstring[0], p, num);
                    242:                        Mstring[0][num] = '\0';
                    243:                }
                    244:                return(loc2-s);
                    245:        }
                    246:        return(0);
                    247: }
                    248: 
                    249: errxx(c)
                    250: {
                    251:        yyerror("RE error");
                    252: }
                    253: 
                    254: #include  "regexp.h"
                    255: yyerror(s)
                    256: 
                    257: {
                    258:        write(2, "expr: ", 6);
                    259:        prt(2, s);
                    260:        exit(2);
                    261: }
                    262: prt(fd, s)
                    263: char *s;
                    264: {
                    265:        write(fd, s, strlen(s));
                    266:        write(fd, "\n", 1);
                    267: }
                    268: char *ltoa(l)
                    269: long l;
                    270: {
                    271:        static str[20];
                    272:        register char *sp = &str[18];
                    273:        register i;
                    274:        register neg = 0;
                    275: 
                    276:        if(l < 0)
                    277:                ++neg, l *= -1;
                    278:        str[19] = '\0';
                    279:        do {
                    280:                i = l % 10;
                    281:                *sp-- = '0' + i;
                    282:                l /= 10;
                    283:        } while(l);
                    284:        if(neg)
                    285:                *sp-- = '-';
                    286:        return ++sp;
                    287: }

unix.superglobalmegacorp.com

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