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

unix.superglobalmegacorp.com

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